這次主要是對(duì)動(dòng)畫做淡如淡出的處理,變形立方體的處理以及漸褪色的變形動(dòng)畫,關(guān)鍵幀動(dòng)畫
淡入淡出動(dòng)畫
是在2個(gè)視圖之間進(jìn)行切換,讓2個(gè)視圖在切換的過(guò)程中進(jìn)行一個(gè)平滑的過(guò)度
若是用變形動(dòng)畫進(jìn)行處理,把第一個(gè)視圖的背景圖淡出的時(shí)候設(shè)置alpha=0的動(dòng)畫,hidden=true,淡入第二張視圖淡入。但是會(huì)有一個(gè)問(wèn)題就是當(dāng)?shù)谝粡垐D淡出的時(shí)候,其后面的內(nèi)容會(huì)顯示出來(lái),破壞了用戶體驗(yàn)。
用一個(gè)方法來(lái)處理動(dòng)畫之間的切換:
核心代碼:
** 第一個(gè)參數(shù):做淡如淡出效果的imageView
第二個(gè)參數(shù):淡入效果的image
第三個(gè)參數(shù):是否顯示雪花的飄落
TransitionCrossDissolve動(dòng)畫的類別,適合2個(gè)視圖動(dòng)畫之間的切換 *
func fadeImageView(imageView: UIImageView, toImage: UIImage, showEffects: Bool) {
UIView.transitionWithView(imageView, duration: 1.0,
options: .TransitionCrossDissolve, animations: {
imageView.image = toImage//通過(guò)變形動(dòng)畫改編image屬性
}, completion: nil)
UIView.animateWithDuration(1.0, delay: 0.0,
options: .CurveEaseOut, animations: {
self.snowView.alpha = showEffects ? 1.0 : 0.0
}, completion: nil)
}
當(dāng)視圖切換的時(shí)候,數(shù)據(jù)也要改變,為頁(yè)面賦值數(shù)據(jù)的方法:
//用于切換不同航班顯示的數(shù)據(jù)
func changeFlightDataTo(data : FlightData , animated : Bool = false) -> () {
if animated {
fadeImageView(bgImageView, toImage: UIImage(named: data.weatherImageName)!, showEffects: data.showWeatherEffects)
}else {
bgImageView.image = UIImage(named: data.weatherImageName)
snowView.hidden = !data.showWeatherEffects
}
summary.text = data.summary
flightNr.text = data.flightNr
gateNr.text = data.gateNr
departingFrom.text = data.departingFrom
arrivingTo.text = data.arrivingTo;
flightStatus.text = data.flightStatus;
delay(seconds: 3.0) {
self.changeFlightDataTo(data.isTakingOff ? parisToRome : londonToParis ,animated: true)
}
}
若何讓視圖顯示的信息以立方體旋轉(zhuǎn)的方式進(jìn)行動(dòng)畫呢?
思路:這個(gè)動(dòng)畫其實(shí)并不是真正意義上的3d效果,而是一個(gè)仿3d的效果。實(shí)現(xiàn)方法就是新增加一個(gè)輔助label,同時(shí)修正輔助label和原始lab e l的高度。使其一個(gè)越來(lái)越高,一個(gè)月來(lái)越矮。當(dāng)達(dá)到顯示的效果時(shí),移除輔助label。動(dòng)畫的方向決定輔助label是從上面呈現(xiàn),還是從下面呈現(xiàn)。
為其方向定義一個(gè)枚舉類型
enum AnimationDirection: Int {
case Positive = 1
case Negative = -1
}
根據(jù)思路寫出這樣一段代碼:
- 第一個(gè)參數(shù)是要?jiǎng)赢嫷膌abel
第二個(gè)參數(shù)是要顯示的新的文本信息
第三個(gè)參數(shù)是標(biāo)示label是從上還是從下顯示文本信息
func cubeTransition(label label: UILabel, text: String, direction: AnimationDirection){
let auxlabel = UILabel(frame: label.frame)
auxlabel.text = text
auxlabel.font = label.font
auxlabel.textAlignment = label.textAlignment
auxlabel.textColor = label.textColor
auxlabel.backgroundColor = label.backgroundColor
/*
第一個(gè)參數(shù)是設(shè)置auxlabel的寬高的1.0標(biāo)示寬度和原 label的寬度相同,高度為原高度的1/10
第二個(gè)參數(shù)是設(shè)置auxlabel的位置的,根據(jù)動(dòng)畫的方向讓label在y方向向上或者向下便宜高度的一半
*/
auxlabel.transform = CGAffineTransformConcat(
CGAffineTransformMakeScale(1.0, 0.1),
CGAffineTransformMakeTranslation(0.0, auxLabelOffset))
label.superview!.addSubview(auxlabel)
UIView.animateWithDuration(0.5, delay: 0.0, options: .CurveEaseOut, animations: {
auxlabel.transform = CGAffineTransformIdentity//讓輔助label變成原label的大小
label.transform = CGAffineTransformConcat(
CGAffineTransformMakeScale(1.0, 0.1),
CGAffineTransformMakeTranslation(0.0, -auxLabelOffset))//讓原label變成輔助label的鏡像
}, completion: {_ in
label.text = auxlabel.text
label.transform = CGAffineTransformIdentity//原label編程原大小
auxlabel.removeFromSuperview()
})
}
展示一種特炫的動(dòng)畫
func moveLabel(label: UILabel, text: String, offset: CGPoint) {
let auxLabel = UILabel(frame: label.frame)
auxLabel.text = text
auxLabel.font = label.font
auxLabel.textAlignment = label.textAlignment
auxLabel.textColor = label.textColor
auxLabel.backgroundColor = UIColor.clearColor()
auxLabel.transform = CGAffineTransformMakeTranslation(offset.x, offset.y)
auxLabel.alpha = 0
view.addSubview(auxLabel)
UIView.animateWithDuration(0.5, delay: 0.0,
options: .CurveEaseIn, animations: {
label.transform = CGAffineTransformMakeTranslation(
offset.x, offset.y)
label.alpha = 0.0
}, completion: nil)
UIView.animateWithDuration(0.25, delay: 0.1,
options: .CurveEaseIn, animations: {
auxLabel.transform = CGAffineTransformIdentity
auxLabel.alpha = 1.0
}, completion: {_ in
//clean up
auxLabel.removeFromSuperview()
label.text = text
label.alpha = 1.0
label.transform = CGAffineTransformIdentity
})
}
效果展示:

關(guān)鍵幀動(dòng)畫
當(dāng)有多個(gè)動(dòng)畫時(shí),我們可以通過(guò)co m p le ti o n閉包關(guān)聯(lián)多個(gè)動(dòng)畫。當(dāng)連續(xù)需要4個(gè)或者更多的動(dòng)畫效果時(shí),為了代碼的可讀性,幀動(dòng)畫就可以實(shí)現(xiàn)。把動(dòng)畫的每一個(gè)階段堪稱一絕一幀動(dòng)畫。實(shí)現(xiàn)動(dòng)畫,只需要做好每一幀的動(dòng)畫。
核心代碼:
func planeDepart(){
let originalCenter = planeImage.center
/*
第一個(gè)參數(shù)是動(dòng)畫執(zhí)行的總時(shí)長(zhǎng)
*/
UIView.animateKeyframesWithDuration(1.5, delay: 0.0, options: [], animations: { () -> Void in
/*
第一個(gè)參數(shù)是動(dòng)畫相對(duì)于總時(shí)長(zhǎng)的開(kāi)始位置,第二個(gè)參數(shù)是動(dòng)畫相對(duì)于總時(shí)長(zhǎng)的執(zhí)行時(shí)間
*/
UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.25, animations: { () -> Void in
self.planeImage.center.x += 80.0
self.planeImage.center.y -= 10.0
})
UIView.addKeyframeWithRelativeStartTime(0.1, relativeDuration: 0.4, animations: { () -> Void in
self.planeImage.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI_4/2))
})
UIView.addKeyframeWithRelativeStartTime(0.25, relativeDuration: 0.25, animations: { () -> Void in
self.planeImage.center.x += 100.0
self.planeImage.center.y -= 50.0
self.planeImage.alpha = 0.0
})
UIView.addKeyframeWithRelativeStartTime(0.51, relativeDuration: 0.01, animations: { () -> Void in
self.planeImage.transform = CGAffineTransformIdentity
self.planeImage.center = CGPoint(x: 0.0, y: originalCenter.y)
})
UIView.addKeyframeWithRelativeStartTime(0.55, relativeDuration: 0.45, animations: { () -> Void in
self.planeImage.alpha = 1.0
self.planeImage.center = originalCenter
})
}, completion: nil)
}
效果展示:
