引言
???????? ???在 App 的開(kāi)發(fā)中,好的用戶體驗(yàn)和絢麗的動(dòng)畫起著十分重要的作用。一般精美的動(dòng)畫需要做很多代碼的編寫才能實(shí)現(xiàn),這往往會(huì)花費(fèi)大量的時(shí)間。為了節(jié)省開(kāi)發(fā)者的時(shí)間,我們注意到 UIView 自帶一些動(dòng)畫函數(shù)。
UIView的動(dòng)畫介紹
???????? ??? UIView 的動(dòng)畫是蘋果對(duì)基礎(chǔ)動(dòng)畫的封裝給開(kāi)發(fā)者使用。UIView 的動(dòng)畫可以修改一些屬性,將其以動(dòng)畫的形式展示出來(lái)??尚薷牡膶傩匀缦拢?strong>frame(尺寸)\bound(大小)\center(中心)\ transform(旋轉(zhuǎn))\alpha(透明度)\ backgroundColor(背景顏色)\ contentStretch(內(nèi)容拉伸) 等。
UIView 的UIViewKeyframeAnimationOptions 和 UIViewAnimationOptions 的介紹
1、UIViewAnimationOptions 的介紹

2CB0AB1D-088A-4EA3-BB76-B31FDC603EE7.png
2、UIViewKeyframeAnimationOptions 的介紹

448720EA-8924-453C-8DA5-B984AA951046.png
其中這四個(gè)選項(xiàng) calculationModeLinear、calculationModeDiscrete、calculationModePaced、calculationModeCubic 的線性圖如下:

2361958-3865dceb3118d461.png
UIview 的動(dòng)畫函數(shù)和參數(shù)的介紹
1、只可以設(shè)置動(dòng)畫內(nèi)容的動(dòng)畫函數(shù)
// TODO: 動(dòng)畫一
func animationA(animationView:UIView) -> Void {
/*!
1、設(shè)置動(dòng)畫時(shí)間
2、設(shè)置動(dòng)畫內(nèi)容
*/
UIView.animate(withDuration:5) {
// 位置和顏色的變換
animationView.frame = CGRect.init(x: self.view.frame.width - 200, y: 50, width:100, height: 200)
}
}
2、可設(shè)置動(dòng)畫時(shí)間、動(dòng)畫內(nèi)容、動(dòng)畫結(jié)束后的內(nèi)容的函數(shù)
// TODO: 動(dòng)畫二
func animationOtherB(animationView:UIView) -> Void {
/*!
1、設(shè)置動(dòng)畫時(shí)間
2、設(shè)置動(dòng)畫內(nèi)容
3、設(shè)置動(dòng)畫結(jié)束后的處理事件
*/
UIView.animate(withDuration: 5, animations: {
// 位置和顏色的變換
animationView.frame = CGRect.init(x: 100, y: 50, width: 100, height: 200)
}) { (isFinish) in
if isFinish {
// 變色
self.View1!.backgroundColor = UIColor.magenta
}
}
}
3、 設(shè)置動(dòng)畫時(shí)間、動(dòng)畫延遲時(shí)間、動(dòng)畫內(nèi)容、動(dòng)畫結(jié)束內(nèi)容的動(dòng)畫函數(shù)
// TODO: 動(dòng)畫四
func animationD(animationView:UIView) -> Void {
/*!
可設(shè)置延時(shí)時(shí)間的動(dòng)畫
@withDuration : 設(shè)置動(dòng)畫時(shí)間
@delay : 設(shè)置動(dòng)畫延遲時(shí)間
@options : 設(shè)置動(dòng)畫的形式
*/
UIView.animate(withDuration: 5, delay: 2, options: .allowUserInteraction, animations: {
// code.... 動(dòng)畫的內(nèi)容
}) { (isFinish) in
// code.... 動(dòng)畫結(jié)束后的處理內(nèi)容
}
}
以上3中動(dòng)畫函數(shù)產(chǎn)生的效果之一如下圖所示:

1.gif

2.gif
4、 彈簧動(dòng)畫函數(shù)
// TODO:動(dòng)畫三
func animationC(animationView:UIView) -> Void {
/*!
彈簧式動(dòng)畫
@withDuration : 設(shè)置動(dòng)畫時(shí)間
@delay : 設(shè)置動(dòng)畫延時(shí)時(shí)間
@usingSpringWithDamping : 設(shè)置阻尼系數(shù)(該數(shù)字越大,動(dòng)畫彈動(dòng)的次數(shù)越少)
@initialSpringVelocity : 設(shè)置初始速度(該數(shù)字越大,震動(dòng)的振幅越大)
@options : 設(shè)置動(dòng)畫的出現(xiàn)形式
*/
UIView.animate(withDuration: 5, delay: 2, usingSpringWithDamping: 0.1, initialSpringVelocity: 10, options: .curveEaseIn, animations: {
// code.... 動(dòng)畫的內(nèi)容
animationView.frame = CGRect.init(x: (self.View1?.center.x)!-20, y: 110, width: 40, height: 40)
}) { (isFinish) in
// code.... 動(dòng)畫結(jié)束后的處理內(nèi)容
animationView.frame = CGRect.init(x: self.View1!.center.x-40, y: 110, width: 80, height: 80)
}
}
其動(dòng)畫效果如下:

3.gif
5、幀動(dòng)畫函數(shù)
// TODO: 動(dòng)畫五
func animationE(animationView:UIView) -> Void {
/*!
幀動(dòng)畫
@withDuration : 設(shè)置動(dòng)畫時(shí)間
@delay : 設(shè)置動(dòng)畫延遲時(shí)間
@options :設(shè)置動(dòng)畫形式
*/
UIView.animateKeyframes(withDuration: 8, delay: 0, options: .calculationModeLinear, animations: {
// code.... 動(dòng)畫的內(nèi)容
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1.0/4, animations: {
animationView.backgroundColor = UIColor.red
})
UIView.addKeyframe(withRelativeStartTime: 1.0/4, relativeDuration: 1.0/4, animations: {
animationView.backgroundColor = UIColor.green
})
UIView.addKeyframe(withRelativeStartTime: 2.0/4, relativeDuration: 1.0/4, animations: {
animationView.backgroundColor = UIColor.blue
})
UIView.addKeyframe(withRelativeStartTime: 3.0/4, relativeDuration: 1.0/4, animations: {
animationView.backgroundColor = UIColor.magenta
})
UIView.addKeyframe(withRelativeStartTime: 4.0/4, relativeDuration: 1.0/4, animations: {
animationView.backgroundColor = UIColor.purple
})
}) { (isFinish) in
// code.... 動(dòng)畫結(jié)束后的處理內(nèi)容
animationView.backgroundColor = UIColor.cyan
}
}
和
// TODO: 關(guān)鍵幀動(dòng)畫的單幀動(dòng)畫設(shè)置
func animationJ(animationView:UIView) -> Void {
/*!
幀動(dòng)畫
@withRelativeStartTime : 設(shè)置動(dòng)畫的開(kāi)始時(shí)間
@relativeDuration : 動(dòng)畫的持續(xù)時(shí)間
*/
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1.0/4, animations: {
animationView.backgroundColor = UIColor.purple
})
}
其產(chǎn)生的動(dòng)畫效果如下:

4.gif
6、UIView的轉(zhuǎn)場(chǎng)動(dòng)畫
1、單個(gè)View的轉(zhuǎn)場(chǎng)動(dòng)畫
func animationG(animationView:UIView) -> Void {
/*!
單個(gè)View的轉(zhuǎn)場(chǎng)動(dòng)畫
@with : 要轉(zhuǎn)場(chǎng)的View
@duration : 轉(zhuǎn)場(chǎng)時(shí)間
@options : 動(dòng)畫的類型
*/
UIView.transition(with: animationView, duration: 5, options:.transitionCurlUp, animations: {
self.imageView4?.image = UIImage.init(named: "2.jpg")
}) { (isFinsish) in
// code .... 轉(zhuǎn)場(chǎng)結(jié)束事件處理
}
}
其產(chǎn)生的動(dòng)畫效果如下:

5.gif
2、 兩個(gè)View 的轉(zhuǎn)場(chǎng)動(dòng)畫
// TODO: 動(dòng)畫六
func animationF(fromView:UIView , toView:UIView) -> Void {
/*!
轉(zhuǎn)場(chǎng)動(dòng)畫
@from : 起始View
@to : 結(jié)束View
@duration : 動(dòng)畫時(shí)間
@options : 動(dòng)畫的形式
*/
UIView.transition(from: fromView, to: toView, duration: 5, options: [ .transitionFlipFromLeft,.showHideTransitionViews]) { (isFinish) in
// code .... 兩個(gè)View的其他處理內(nèi)容
}
}
其產(chǎn)生的動(dòng)畫效果如下:

6.gif
7、UIView 的基本動(dòng)畫的寫法如下
// TODO: 動(dòng)畫的一般寫法
func basicAnimation() -> Void {
// 開(kāi)始某個(gè)動(dòng)畫
UIView.beginAnimations("animation", context: nil)
// 設(shè)置動(dòng)畫時(shí)間
UIView.setAnimationDuration(5)
// 設(shè)置動(dòng)畫的延時(shí)時(shí)間
UIView.setAnimationDelay(0.25)
// 設(shè)置動(dòng)畫的效果
UIView.setAnimationCurve(.easeInOut)
// 設(shè)置動(dòng)畫是否重復(fù),0為無(wú)限重復(fù)
UIView.setAnimationRepeatCount(0)
// 設(shè)置動(dòng)畫的代理
UIView.setAnimationDelegate(self)
// 設(shè)置動(dòng)畫將要觸發(fā)的時(shí)調(diào)用的方法
UIView.setAnimationWillStart(#selector(willStartMethod))
// 設(shè)置動(dòng)畫結(jié)束時(shí)觸發(fā)的方法
UIView.setAnimationDidStop(#selector(didStopMethod))
// 設(shè)置動(dòng)畫是否可用
UIView.setAnimationsEnabled(true)
// 設(shè)置動(dòng)畫是否從當(dāng)前狀態(tài)開(kāi)始(例如:一個(gè)動(dòng)畫正在播放時(shí),我們要進(jìn)行下一個(gè)動(dòng)畫,如果設(shè)置為 true 時(shí),動(dòng)畫將從當(dāng)前動(dòng)畫狀態(tài)開(kāi)始動(dòng)畫。為 false時(shí)是等上一個(gè)動(dòng)畫停止時(shí),開(kāi)始下一個(gè)動(dòng)畫)
UIView.setAnimationBeginsFromCurrentState(true)
// 設(shè)置動(dòng)畫開(kāi)始的時(shí)間
UIView.setAnimationStart(Date.init())
// 設(shè)置動(dòng)畫是否執(zhí)行動(dòng)畫回路,前提 UIView.setAnimationRepeatCount(0) 為 0
UIView.setAnimationRepeatAutoreverses(true)
// 設(shè)置單個(gè)View的轉(zhuǎn)場(chǎng)動(dòng)畫
UIView.setAnimationTransition(.flipFromLeft, for: self.view, cache: true)
// 設(shè)置動(dòng)畫的結(jié)束
UIView.commitAnimations()
}
// 動(dòng)畫代理觸發(fā)事件
@objc func willStartMethod() {
// 動(dòng)畫將要開(kāi)始執(zhí)行觸發(fā)的代理事件
}
@objc func didStopMethod() {
// 動(dòng)畫結(jié)束后觸發(fā)的方法
}