CAAnimation是什么鸯匹?
CAAnimation 是一個抽象動畫類穿扳。 遵循并實現(xiàn)實現(xiàn)了 CAMediaTiming 和 CAAciotn 兩個協(xié)議。 CAAnimation 無法直接使用,想要為 Core Animation 的圖層或 Scene Kit 對象設(shè)置動畫爵政,應(yīng)該使用其子類 CABasicAnimation
,CAKeyframeAnimation
陶缺,CAAnimationGroup
或CATransition
的實例钾挟。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)。
一般情況下夕土,使用 fromValue
和 toValue
即可馆衔。
-
使用示例:移動一個視圖
這里寫圖片描述
// …… 省略了視圖部分
// 創(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ù)組
注:
- 動畫組中的動畫不會被壓縮,超出動畫時長的部分將會被剪掉
- 動畫組中的動畫的
delegate
與removedOnCompletion
屬性將會被忽略 由于忽略了removedOnCompletion
屬性穗熬,動畫結(jié)束圖層會恢復(fù)到動畫前的狀態(tài) -
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)屬性者冤。