iOS 動畫篇 - CAAnimation初識

CAAnimation是什么鸯匹?

CAAnimation 是一個抽象動畫類穿扳。 遵循并實現(xiàn)實現(xiàn)了 CAMediaTiming 和 CAAciotn 兩個協(xié)議。 CAAnimation 無法直接使用,想要為 Core Animation 的圖層或 Scene Kit 對象設(shè)置動畫爵政,應(yīng)該使用其子類 CABasicAnimationCAKeyframeAnimation陶缺,CAAnimationGroupCATransition 的實例钾挟。Core Animation可以用在 Mac OS X 和 iOS 平臺。Core Animation 的動畫執(zhí)行過程都是在后臺操作的饱岸,不會阻塞主線程掺出。

注: 要注意的是,Core Animation是直接作用在圖層上的伶贰,即 CALayer 蛛砰,并非視圖 UIView。當動畫之行完畢黍衙,視圖的 frame 并沒有真實地改變。

認識 CAAnimation

  • CAAnimation 類中的常用屬性荠诬,這些是有關(guān)動畫效果的幾個屬性琅翻。
// 動畫的節(jié)奏
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
/*
系統(tǒng)給出的幾種類型
 - kCAMediaTimingFunctionLinear //線性節(jié)奏,就是勻速
 - kCAMediaTimingFunctionEaseIn //淡入柑贞,緩慢加速進入方椎,然后勻速
 - kCAMediaTimingFunctionEaseOut //淡出,勻速钧嘶,然后緩慢減速移除
 - kCAMediaTimingFunctionEaseInEaseOut //淡入淡出棠众,結(jié)合以上兩者
 - kCAMediaTimingFunctionDefault //默認效果
*/

// 動畫代理,注意該代理使用的是strong有决,注意釋放問題
@property(nullable, strong) id <CAAnimationDelegate> delegate;
// 開始和結(jié)束的代理
// 開始
-(void)animationDidStart:(CAAnimation *)anim;
// 結(jié)束闸拿、flag表示動畫正常結(jié)束還是被打斷移除
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;

// 是否在播放完成后移除,配合 fillMode = kCAFillModeForwards 可以保留最終的播放效果
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
  • CAMediaTiming 協(xié)議的定義的屬性

該協(xié)議有關(guān)于動畫時間相關(guān)的书幕,例如開始結(jié)束的時間新荤、重復(fù)時間等。

@property CFTimeInterval beginTime; // 動畫開始時間(滯后時間)
@property CFTimeInterval duration; // 動畫持續(xù)時間
@property float speed; // 速度 例:如果speed是2台汇,duration是3苛骨,那么經(jīng)過1.5秒,動畫播放完成苟呐。
@property CFTimeInterval timeOffset; // 動畫開始播放偏移時刻
@property float repeatCount; // 重復(fù)次數(shù)
@property CFTimeInterval repeatDuration; // 重復(fù)時間
@property BOOL autoreverses; // 自動執(zhí)行相反動畫
@property(copy) NSString *fillMode; // 播放結(jié)束后的狀態(tài)
  • 使用步驟

1痒芝、初始化一個CAAnimation子類對象,設(shè)置一些動畫相關(guān)屬性牵素;
2严衬、通過調(diào)用CALayer的-addAnimation:forKey:方法增加CAAnimation對象到CALayer上
3、通過調(diào)用CALayer的-removeAnimationForKey:方法可以停止CALayer中的動畫两波。

注:一個動畫對象可以作用于多個視圖瞳步,無需多次創(chuàng)建實例闷哆。

CABasicAnimation 基礎(chǔ)動畫

CABasicAnimation 可以看作是特殊的 CAKeyframeAnimation 動畫,因為只需要指定一個初始狀態(tài)和一個終止狀態(tài)即可单起。

CABasicAnimation 是 CAPropertyAnimation 的子類抱怔,也叫屬性動畫,也就是針對視圖的圖層中的可動畫屬性進行動畫操作嘀倒,例如圖層的位置 position屈留、透明度 opacity 等,不是所有的屬性都是可以進行動畫的测蘑。

動畫狀態(tài)解析:

fromValue // 初始狀態(tài)灌危,即動畫開始的狀態(tài)點
toValue // 終止狀態(tài),即動畫終止的狀態(tài)點
byValue // 狀態(tài)的增量

這三個值不能全為空碳胳,因為這樣你就一個狀態(tài)也沒有指定勇蝙。
也不能全不為空,因為這樣你就指定了三個狀態(tài)挨约,系統(tǒng)也不知道選哪兩個味混。
若果你指定了一個狀態(tài),那系統(tǒng)將自動以當前狀態(tài)作為另一個狀態(tài)诫惭。
若你指定了兩個狀態(tài)翁锡,則系統(tǒng)以這兩個狀態(tài)作為始末狀態(tài)。
一般情況下夕土,使用 fromValuetoValue 即可馆衔。

  • 使用示例:移動一個視圖


    這里寫圖片描述
// …… 省略了視圖部分
// 創(chuàng)建一個動畫,針對視圖位置 position 進行動畫效果
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.duration = 1.0f; //動畫時間
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)]; //移動到新的位置
animation.beginTime = CACurrentMediaTime() + 0; //動畫開始的時間
animation.autoreverses = YES; //動畫結(jié)束時是否執(zhí)行逆動畫
animation.repeatCount = HUGE_VALF; //重復(fù)次數(shù)(無限大)
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; //速率
// animation.removedOnCompletion = NO;
// animation.fillMode = kCAFillModeForwards;
[testView.layer addAnimation:animation forKey:@"animation"]; //將動畫添加到layer上
  • 可動畫的屬性一覽

初始化中的 animationWithKeyPath 參數(shù)表示 layer 可進行動畫的屬性怨绣,一般常用的屬性有以下多種角溃。

KeyPath 說明 樣例
transform.scale 縮放 @(0.5)
transform.scale.x 寬的比例 @(0.5)
transform.scale.y 寬的比例 @(0.5)
opacity 透明度 @(0.5)
cornerRadius 圓角 @(0.5)
transform.rotation.x 圍繞x軸旋轉(zhuǎn) @(M_PI)
transform.rotation.y 圍繞y軸旋轉(zhuǎn) @(M_PI)
transform.rotation.z 圍繞z軸旋轉(zhuǎn) @(M_PI)
strokeStart 結(jié)合CAShapeLayer使用 賦值多變
strokeEnd 結(jié)合CAShapeLayer使用 賦值多變
bounds 大小,中心不變 [NSValue valueWithCGRect:CGRectMake(0, 0, 100, 100)]
position 位置中心點 [NSValue valueWithCGRect:CGPointMake(100, 100)]
contents 顯示的內(nèi)容 (id)[UIImage imageNamed:@”imageName”].CGImage
  • 動畫狀態(tài)的監(jiān)聽

如果需要在動畫執(zhí)行的開始或者結(jié)束做點什么的時候梨熙,可以設(shè)置動畫代理來完成狀態(tài)監(jiān)聽开镣。

- (void)animationDidStart:(CAAnimation *)anim{
    NSLog(@"動畫開始");
}
// flag表明了動畫是自然結(jié)束還是被打斷,比如調(diào)用了removeAnimationForKey:方法咽扇,flag為NO邪财,如果是正常結(jié)束,flag為YES质欲。
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    NSLog(@"%@",flag?@"自然結(jié)束":@"被系統(tǒng)或者人為結(jié)束");
}

注:此代理是 strong 強引用類型树埠,需要手動置成 nil

CAKeyframeAnimation 關(guān)鍵幀動畫

CAKeyframeAnimation 跟 CABasicAnimation 的區(qū)別是:CABasicAnimation只能從一個數(shù)值(fromValue)變到另一個數(shù)值(toValue)嘶伟。而 CAKeyframeAnimation 可以使用狀態(tài)數(shù)組(關(guān)鍵幀數(shù)組)來展示不同的運動情況怎憋。

簡單理解,CABasicAnimation 是針對兩個狀態(tài)的變化,CAKeyframeAnimation 是針對一組狀態(tài)的變化绊袋。

CAKeyframeAnimation 是 CAPropertyAnimation 的子類毕匀,同樣也是屬性動畫。

動畫狀態(tài)解析:

values //NSArray對象癌别,里面的元素稱為“關(guān)鍵幀” (keyframe)皂岔。動畫對象會在指定的時間(duration)內(nèi),依次顯示values數(shù)組中的每一個關(guān)鍵幀
path //讓圖層根據(jù)路徑移動展姐。Path只對CALayer的anchorPoint和position其作用躁垛。如果你設(shè)置了path,那么values將被忽略
keyTimes //對應(yīng)的關(guān)鍵幀制定對應(yīng)的時間點數(shù)組圾笨。其取值范圍為0到1.0教馆。如果沒有設(shè)置,則關(guān)鍵幀平分duration
timingFunctions //對應(yīng)關(guān)鍵幀制定對應(yīng)的速率擂达。

使用示例:


這里寫圖片描述
// …… 省略layer部分
// 創(chuàng)建一個關(guān)鍵幀動畫
CAKeyframeAnimation *aniByValues = [CAKeyframeAnimation animationWithKeyPath:@"position"];
aniByValues.duration = 3.0f;
aniByValues.repeatCount = HUGE_VALF;
// 設(shè)置關(guān)鍵幀位置數(shù)組
aniByValues.values = @[[NSValue valueWithCGPoint:testLayer.position],[NSValue valueWithCGPoint:CGPointMake(kScreenWidth-30, testLayer.frame.origin.y)],[NSValue valueWithCGPoint:CGPointMake(kScreenWidth-30, testLayer.frame.origin.y+100)],[NSValue valueWithCGPoint:CGPointMake(30, testLayer.frame.origin.y+100)],[NSValue valueWithCGPoint:testLayer.position],];
// 將動畫添加圖層上
[testLayer addAnimation:aniByValues forKey:@"position"];

CAAnimationGroup 動畫組

可以保存一組動畫對象土铺,將 CAAnimationGroup 對象添加到圖層上后,組中所有動畫對象可以同時并發(fā)運行板鬓。

CAAnimationGroup 是 CAAnimation 的子類舒憾。

屬性解析:

animations // 存放并發(fā)執(zhí)行的所有動畫數(shù)組

注:

  1. 動畫組中的動畫不會被壓縮,超出動畫時長的部分將會被剪掉
  2. 動畫組中的動畫的 delegateremovedOnCompletion 屬性將會被忽略 由于忽略了 removedOnCompletion 屬性穗熬,動畫結(jié)束圖層會恢復(fù)到動畫前的狀態(tài)
  3. animations 存放并發(fā)執(zhí)行的所有動畫數(shù)組元素為CAAnimation的子類

CATransition 轉(zhuǎn)場動畫

CAAnimation 的子類,用于做轉(zhuǎn)場動畫丁溅,能夠為圖層提供移出屏幕和移入屏幕的動畫效果唤蔗。iOS 比 Mac OS X 的轉(zhuǎn)場動畫效果少一點。UINavigationController就是通過CATransition 實現(xiàn)了將控制器的視圖推入屏幕的動畫效果窟赏。

屬性解析:

type //動畫過渡類型:fade妓柜、moveIn、push涯穷、reveal棍掐。 默認fade
/*
  kCATransitionFade //交叉淡化過渡(不支持過渡方向)
  kCATransitionMoveIn //新視圖移到舊視圖上面 
  kCATransitionPush //新視圖把舊視圖推出去
  kCATransitionReveal //將舊視圖移開,顯示下面的新視圖
*/
subtype //動畫過渡方向
/* 過渡方向
  kCATransitionFromRight 
  kCATransitionFromLeft
  kCATransitionFromBottom 
  kCATransitionFromTop
*/
startProgress //動畫起點(在整體動畫的百分比)
endProgress //動畫終點(在整體動畫的百分比)

轉(zhuǎn)場動畫 type,除了系統(tǒng)給定的四種拷况,還有私有的動畫可以使用作煌,不過只能使用字符串來設(shè)置。

  • cube //立方體翻滾效果
  • oglFlip //上下左右翻轉(zhuǎn)效果
  • suckEffect //收縮效果赚瘦,如一塊布被抽走(不支持過渡方向)
  • rippleEffect //滴水效果(不支持過渡方向)
  • pageCurl //向上翻頁效果
  • pageUnCurl //向下翻頁效果
  • cameraIrisHollowOpen //相機鏡頭打開效果(不支持過渡方向)
  • cameraIrisHollowClose //相機鏡頭關(guān)上效果(不支持過渡方向)

使用示例


動畫效果
CATransition *transition = [CATransition animation];
transition.type = @"cube"; // 動畫過渡類型
transition.subtype = kCATransitionFromRight; // 動畫過渡方向
transition.duration = 1; // 動畫持續(xù)1s
[self.imageView.layer addAnimation:transition forKey:@"KCATransitionAnimation"];

使用場景:imageView切換圖片粟誓,控制器的 push 或 modal 方法等。

CASpringAnimation 彈性動畫

CASpringAnimation 是 CABasicAnimation 基本動畫的子類起意,在 iOS9 之后引入鹰服,可以實現(xiàn)彈性動畫,例如籃球掉落,彈簧收縮悲酷。
CASpringAnimation 動畫引入物理引擎套菜,通過設(shè)置質(zhì)量,阻尼系數(shù)等值模擬物體的彈性效果设易。

屬性解析:

mass //質(zhì)量逗柴,影響慣性、拉伸幅度
stiffness //剛度系數(shù)亡嫌,剛度系數(shù)越大嚎于,形變產(chǎn)生的力就越大,運動越快
damping //阻尼系數(shù)挟冠,阻止彈簧伸縮的系數(shù)于购,阻尼系數(shù)越大,停止越快
CGFloat initialVelocity //初始速率  
settlingDuration //結(jié)算時間知染,可根據(jù)當前的動畫參數(shù)估算彈簧動畫到停止時的估算時間

使用示例


小球落地效果
CASpringAnimationa *animation = [CASpringAnimation animationWithKeyPath:@"position.y"];
animation.damping = 5;                 // 阻尼系數(shù)
animation.stiffness = 100;             // 剛度系數(shù)
animation.mass = 1;                    // 質(zhì)量
animation.initialVelocity = 0;         // 初始速率
animation.duration = animation.settlingDuration;  //結(jié)束時間
animation.fromValue = @(self.layer.position.y);
animation.toValue = @(self.layer.position.y+100);
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;

Demo地址

總結(jié)

CAAnimation 是一個抽象動畫類肋僧,無法直接使用,需要使用它的子類控淡,動畫分為兩大類:屬性動畫和轉(zhuǎn)場動畫嫌吠。屬性動畫顧名思義,針對圖層可動畫屬性進行動畫掺炭,轉(zhuǎn)場動畫通常用于視圖切換辫诅,例如A視圖切換為B視圖。CAAnimation 針對的是圖層而非視圖涧狮,因此默認情況下炕矮,它在完成動畫后恢復(fù)到最初狀態(tài),且不會改變視圖的相關(guān)屬性者冤。

拓展閱讀

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肤视,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涉枫,更是在濱河造成了極大的恐慌邢滑,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愿汰,死亡現(xiàn)場離奇詭異困后,居然都是意外死亡,警方通過查閱死者的電腦和手機尼桶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門操灿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人泵督,你說我怎么就攤上這事趾盐。” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵救鲤,是天一觀的道長久窟。 經(jīng)常有香客問我,道長本缠,這世上最難降的妖魔是什么斥扛? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮丹锹,結(jié)果婚禮上稀颁,老公的妹妹穿的比我還像新娘。我一直安慰自己楣黍,他們只是感情好匾灶,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著租漂,像睡著了一般阶女。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哩治,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天秃踩,我揣著相機與錄音,去河邊找鬼业筏。 笑死憔杨,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的蒜胖。 我是一名探鬼主播芍秆,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼翠勉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起霉颠,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤对碌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蒿偎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體朽们,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年诉位,在試婚紗的時候發(fā)現(xiàn)自己被綠了骑脱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡苍糠,死狀恐怖叁丧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤拥娄,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布蚊锹,位于F島的核電站,受9級特大地震影響稚瘾,放射性物質(zhì)發(fā)生泄漏牡昆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一摊欠、第九天 我趴在偏房一處隱蔽的房頂上張望丢烘。 院中可真熱鬧,春花似錦些椒、人聲如沸播瞳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狐史。三九已至,卻和暖如春说墨,著一層夾襖步出監(jiān)牢的瞬間骏全,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工尼斧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留姜贡,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓棺棵,卻偏偏與公主長得像楼咳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子烛恤,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容