快速上手核心動畫

1、什么是核心動畫

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


核心動畫.png

上圖中的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)

Core Animation類圖.png

核心動畫中可以直接使用的類有:

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"];
CABasicAnimation.gif

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"];
CAKeyframeAnimation.gif

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"];
CAAnimationGroup.gif

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"];
CATransition.gif

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"];
CASpringAnimation.gif

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];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 出處:http://www.cnblogs.com/dongliu/ 本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)...
    i_蘇閱讀 371評論 0 1
  • 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復(fù)雜,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,688評論 6 30
  • 如果想讓事情變得順利,只有靠自己--夏爾·紀(jì)堯姆 上一章介紹了隱式動畫的概念。隱式動畫是在iOS平臺創(chuàng)建動態(tài)用戶界...
    夜空下最亮的亮點(diǎn)閱讀 2,090評論 0 1
  • 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復(fù)雜,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,262評論 5 13
  • 顯式動畫 顯式動畫,它能夠?qū)σ恍傩宰鲋付ǖ淖远x動畫,或者創(chuàng)建非線性動畫,比如沿著任意一條曲線移動。 屬性動畫 ...
    清風(fēng)沐沐閱讀 2,091評論 1 5

友情鏈接更多精彩內(nèi)容