1、什么是核心動畫
Core Animation是一套包含圖形繪制、投影、動畫的Objective-C類集合,該框架包含在QuartzCore.framework中,它因為被用于處理更為強(qiáng)大的平滑的轉(zhuǎn)場效果而引入OS X Leopard和iOS而出名。Core Animation和其它框架的位置關(guān)系如下圖所示:

上圖中的OpenGL ES是個C語言寫的非常底層的圖形處理框架,是個移動設(shè)備上繪制2D和3D計算機(jī)圖形的標(biāo)準(zhǔn)開源庫,廣泛地被用在游戲的圖形繪制上,負(fù)責(zé)直接驅(qū)動GPU,效率非常高,缺點(diǎn)是使用起來異常復(fù)雜。
Core Animation是對OpenGL ES的Objective-C封裝,具有與OpenGL ES幾乎等價的高性能,卻隱藏了OpenGL ES的復(fù)雜性。
2、核心動畫類的層次結(jié)構(gòu)

核心動畫中可以直接使用的類有:
CABasicAnimation
CAKeyframeAnimation
CAAnimationGroup
CATransition
CASpringAnimation
常用屬性有:
duration : 動畫的持續(xù)時間
beginTime : 動畫的開始時間
repeatCount : 動畫的重復(fù)次數(shù)
autoreverses : 執(zhí)行的動畫按照原動畫返回執(zhí)行
timingFunction : 控制動畫的顯示節(jié)奏系統(tǒng)提供五種值選擇,分別是:
kCAMediaTimingFunctionLinear 線性動畫
kCAMediaTimingFunctionEaseIn 先慢后快
kCAMediaTimingFunctionEaseOut 先快后慢
kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢
kCAMediaTimingFunctionDefault 默認(rèn),也屬于中間比較快fillMode:決定當(dāng)前對象在非active時間段的行為.比如動畫開始之前,動畫結(jié)束之后
beginTime:可以用來設(shè)置動畫延遲執(zhí)行時間,若想延遲2s,就設(shè)置為CACurrentMediaTime()+2,CACurrentMediaTime()為圖層的當(dāng)前時間
delegate : 動畫代理。能夠檢測動畫的執(zhí)行和結(jié)束。
@interface NSObject (CAAnimationDelegate)
@optional
- (void)animationDidStart:(CAAnimation *)anim;
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
@end
path:關(guān)鍵幀動畫中的執(zhí)行路徑
type : 過渡動畫的動畫類型,系統(tǒng)提供了四種過渡動畫。
kCATransitionFade 漸變效果
kCATransitionMoveIn 進(jìn)入覆蓋效果
kCATransitionPush 推出效果
kCATransitionReveal 揭露離開效果subtype : 過渡動畫的動畫方向
kCATransitionFromRight 從右側(cè)進(jìn)入
kCATransitionFromLeft 從左側(cè)進(jìn)入
kCATransitionFromTop 從頂部進(jìn)入
kCATransitionFromBottom 從底部進(jìn)入
3、常見類介紹
CABasicAnimation
CABasicAnimation可以設(shè)定keyPath的起點(diǎn),終點(diǎn)的值,動畫會沿著設(shè)定點(diǎn)進(jìn)行移動,CABasicAnimation可以看成是只有兩個關(guān)鍵點(diǎn)的特殊的CAKeyFrameAnimation。
重要屬性:
- fromValue : keyPath對應(yīng)的初始值
- toValue : keyPath對應(yīng)的結(jié)束值
基礎(chǔ)動畫主要提供了對于CALayer對象中的可變屬性進(jìn)行簡單動畫的操作。比如:位移、透明度、縮放、旋轉(zhuǎn)、背景色等等。
注意點(diǎn):
如果 fillMode = kCAFillModeForwards 和 removedOnComletion = NO,那么在動畫執(zhí)行完畢后,圖層會保持顯示動畫執(zhí)行后的狀態(tài)。但在實質(zhì)上,圖層的屬性值還是動畫執(zhí)行前的初始值,并沒有真正被改變。
CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnima.duration = 0.8;
positionAnima.fromValue = @(_iconView.center.y);
positionAnima.toValue = @(_iconView.center.y-30);
positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
positionAnima.repeatCount = HUGE_VALF;
positionAnima.repeatDuration = 2;
positionAnima.removedOnCompletion = NO;
positionAnima.fillMode = kCAFillModeBackwards;
positionAnima.delegate = self;
[positionAnima setValue:@"PositionAnima" forKey:@"AnimationKey"];
[_iconView.layer addAnimation:positionAnima forKey:@"AnimationMoveY"];

CAKeyframeAnimation
可以設(shè)定keyPath起點(diǎn)、中間關(guān)鍵點(diǎn)(不止一個)、終點(diǎn)的值,每一幀所對應(yīng)的時間,動畫會沿著設(shè)定點(diǎn)進(jìn)行移動。
重要屬性:
- values : 鍵幀數(shù)組對象,里面每一個元素即為一個關(guān)鍵幀,動畫會在對應(yīng)的時間段內(nèi),依次執(zhí)行數(shù)組中每一個關(guān)鍵幀的動畫。
- path : 動畫路徑對象,可以設(shè)置一個CGPathRef\CGMutablePathRef,讓層跟著路徑移動。path只對CALayer的anchorPoint和position起作用。如果你設(shè)置了path,那么values將被忽略。
- keyTimes : 可以為對應(yīng)的關(guān)鍵幀指定對應(yīng)的時間點(diǎn),其取值范圍為0到1.0,keyTimes中的每一個時間值都對應(yīng)values中的每一幀.如果沒有設(shè)置該屬性,則每一幀的時間平分。
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
animation.duration = 0.25;
animation.repeatCount = 10;
animation.values = @[@0.0,@(-M_PI_4/4),@0.0,@(M_PI_4/4),@0.0];
animation.keyTimes = @[@0.0,@0.25,@0.5,@0.75,@1.0];
[_iconView.layer addAnimation:animation forKey:@"AnimationKey"];

CAAnimationGroup
CAAnimation的子類,可以保存一組動畫對象,將CAAnimationGroup對象加入層后,組中所有動畫對象可以同時并發(fā)運(yùn)行。
重要屬性:
- animations : 用來保存一組動畫對象的NSArray
CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnima.fromValue = @(self.iconView.center.y);
positionAnima.toValue = @(self.iconView.center.y-30);
positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
transformAnima.fromValue = @(0);
transformAnima.toValue = @(M_PI);
transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CAAnimationGroup *animaGroup = [CAAnimationGroup animation];
animaGroup.duration = 2.0f;
animaGroup.fillMode = kCAFillModeForwards;
animaGroup.removedOnCompletion = NO;
animaGroup.animations = @[positionAnima,transformAnima];
[self.iconView.layer addAnimation:animaGroup forKey:@"Animation"];

CATransition
轉(zhuǎn)場動畫,比UIVIew轉(zhuǎn)場動畫具有更多的動畫效果,比如Nav的默認(rèn)Push視圖的效果就是通過CATransition的kCATransitionPush類型來實現(xiàn)。
重要屬性:
- type :動畫過渡類型
Apple 官方的SDK其實只提供了四種過渡效果。
kCATransitionFade 漸變效果
kCATransitionMoveIn 進(jìn)入覆蓋效果
kCATransitionPush 推出效果
kCATransitionReveal 揭露離開效果
還有一些私有API的動畫類型,效果很炫酷,不過不推薦使用。比如:"cube"、"suckEffect"、"oglFlip"、"rippleEffect"、"pageCurl"、"pageUnCurl"、"cameraIrisHollowOpen"、"cameraIrisHollowClose"等等。
subtype :動畫過渡方向
kCATransitionFromRight 從右側(cè)進(jìn)入
kCATransitionFromLeft 從左側(cè)進(jìn)入
kCATransitionFromTop 從頂部進(jìn)入
kCATransitionFromBottom 從底部進(jìn)入startProgress :動畫起點(diǎn)(在整體動畫的百分比)
endProgress :動畫終點(diǎn)(在整體動畫的百分比)
CATransition * transitionAnima = [CATransition animation];
transitionAnima.type = kCATransitionMoveIn;
transitionAnima.subtype = kCATransitionFromRight;
transitionAnima.duration = 2.5;
_iconView.image = [UIImage imageNamed:@"paopao"];
[_iconView.layer addAnimation:transitionAnima forKey:@"transitionAnima"];

CASpringAnimation
CASpringAnimation是iOS9新加入動畫類型,是CABasicAnimation的子類,用于實現(xiàn)彈簧動畫。
CASpringAnimation和UIView的SpringAnimation對比:
1.CASpringAnimation 可以設(shè)置更多影響彈簧動畫效果的屬性,可以實現(xiàn)更復(fù)雜的彈簧動畫效果,且可以和其他動畫組合。
2.UIView的SpringAnimation實際上就是通過CASpringAnimation來實現(xiàn)。
重要屬性:
- mass:質(zhì)量(影響彈簧的慣性,質(zhì)量越大,彈簧慣性越大,運(yùn)動的幅度越大)
- stiffness:彈性系數(shù)(彈性系數(shù)越大,彈簧的運(yùn)動越快)
- damping:阻尼系數(shù)(阻尼系數(shù)越大,彈簧的停止越快)
- initialVelocity:初始速率(彈簧動畫的初始速度大小,彈簧運(yùn)動的初始方向與初始速率的正負(fù)一致,若初始速率為0,表示忽略該屬性)
- settlingDuration:結(jié)算時間(根據(jù)動畫參數(shù)估算彈簧開始運(yùn)動到停止的時間,動畫設(shè)置的時間最好根據(jù)此時間來設(shè)置)
CASpringAnimation * springAnima = [CASpringAnimation animationWithKeyPath:@"bounds"];
springAnima.mass = 10.0; //質(zhì)量,影響圖層運(yùn)動時的彈簧慣性,質(zhì)量越大,彈簧拉伸和壓縮的幅度越大
springAnima.stiffness = 5000; //剛度系數(shù)(勁度系數(shù)/彈性系數(shù)),剛度系數(shù)越大,形變產(chǎn)生的力就越大,運(yùn)動越快
springAnima.damping = 100.0;//阻尼系數(shù),阻止彈簧伸縮的系數(shù),阻尼系數(shù)越大,停止越快
springAnima.initialVelocity = 3.0;//初始速率,動畫視圖的初始速度大小;速率為正數(shù)時,速度方向與運(yùn)動方向一致,速率為負(fù)數(shù)時,速度方向與運(yùn)動方向相反
springAnima.duration = springAnima.settlingDuration;
springAnima.toValue = [NSValue valueWithCGRect:CGRectMake(100, 200, 200, 200)];
springAnima.removedOnCompletion = NO;
springAnima.fillMode = kCAFillModeForwards;
springAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.iconView.layer addAnimation:ani forKey:@"boundsAni"];

CATransaction
CoreAnimation中還有一個非常重要的類:CATransaction事務(wù)類,這個可以同時設(shè)置多個layer層的動畫效果??梢酝ㄟ^隱式和顯式兩種方式來進(jìn)行動畫操作。
事務(wù)實際上是Core Animation用來包含一系列屬性動畫集合的機(jī)制,任何用指定事務(wù)去改變可以做動畫的圖層屬性都不會立刻發(fā)生變化,而是當(dāng)事務(wù)一旦提交的時候開始用一個動畫過渡到新值。
事務(wù)是通過CATransaction類來做管理,這個類的設(shè)計有些奇怪,不像你從它的命名預(yù)期的那樣去管理一個簡單的事務(wù),而是管理了一疊你不能訪問的事務(wù)。CATransaction沒有屬性或者實例方法,并且也不能用+alloc和-init方法創(chuàng)建它。但是可以用+begin和+commit分別來入?;蛘叱鰲?。
任何可以做動畫的圖層屬性都會被添加到棧頂?shù)氖聞?wù),你可以通過+setAnimationDuration:方法設(shè)置當(dāng)前事務(wù)的動畫時間,或者通過+animationDuration方法來獲取值(默認(rèn)0.25秒)。
Core Animation在每個run loop周期中自動開始一次新的事務(wù)(run loop是iOS負(fù)責(zé)收集用戶輸入,處理定時器或者網(wǎng)絡(luò)事件并且重新繪制屏幕的東西),即使你不顯式的用[CATransaction begin]開始一次事務(wù),任何在一次run loop循環(huán)中屬性的改變都會被集中起來,然后做一次0.25秒的動畫。
事務(wù)的作用:保證一個或多個layer的一個或多個屬性變化同時進(jìn)行
事務(wù)分為隱式和顯式:
1.隱式:沒有明顯調(diào)用事務(wù)的方法,由系統(tǒng)自動生成事務(wù)。比如直接設(shè)置一個layer的position屬性,則會在當(dāng)前線程自動生成一個事務(wù),并在下一個runLoop中自動commit事務(wù)。
2.顯式:明顯調(diào)用事務(wù)的方法([CATransaction begin]和[CATransaction commit])。
對layer層的屬性操作,都會形成隱式動畫,要使用隱式動畫,需要關(guān)閉layer層的animation動畫屬性,使用下面的方法:
//關(guān)閉animation動畫效果,開啟隱式動畫
+ (BOOL)disableActions;
+ (void)setDisableActions:(BOOL)flag;
事務(wù)的可設(shè)置屬性(會覆蓋隱式動畫的設(shè)置):
- animationDuration:動畫時間
- animationTimingFunction:動畫時間曲線
- disableActions:是否關(guān)閉動畫
- completionBlock:動畫執(zhí)行完畢的回調(diào)
事務(wù)支持嵌套使用:當(dāng)最外層的事務(wù)commit后動畫才會開始。
使用實例:
[CATransaction begin];
[CATransaction setAnimationDuration:2.0];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
self.iconView.layer.bounds = self.showView.layer.bounds;
[CATransaction commit];