1蒸甜、UIView和核心動(dòng)畫區(qū)別?
核心動(dòng)畫只能添加到CALayer仰担, 核心動(dòng)畫一切都是假象骇径,并不會(huì)改變真實(shí)的值米间。如果需要與用戶交互就使用UIView的動(dòng)畫. 不需要與用戶交互可以使用核心動(dòng)畫。
在轉(zhuǎn)場(chǎng)動(dòng)畫中栅隐,核心動(dòng)畫的類型比較多塔嬉。根據(jù)?個(gè)路徑做動(dòng)畫玩徊,只能用核心動(dòng)畫(幀動(dòng)畫) 、動(dòng)畫組:同時(shí)做多個(gè)動(dòng)畫谨究。
2恩袱、核心動(dòng)畫的分類
核心動(dòng)畫繼承結(jié)構(gòu)
圖中的黑色虛線代表“繼承”某個(gè)類,紅色虛線代表“遵守”某個(gè)協(xié)議
2.1 CAAnimation
CAAnimation
是所有動(dòng)畫對(duì)象的父類胶哲,負(fù)責(zé)控制動(dòng)畫的持續(xù)時(shí)間和速度畔塔,是個(gè)抽象類,不能直接使用鸯屿,應(yīng)該使用它具體的子類
屬性解讀
屬性 | 描述 |
---|---|
duration |
動(dòng)畫的持續(xù)時(shí)間 |
repeatCount |
重復(fù)次數(shù)澈吨,無限循環(huán)可以設(shè)置HUGE_VALF或者M(jìn)AXFLOAT |
repeatDuration |
重復(fù)時(shí)間 |
beginTime |
可以用來設(shè)置動(dòng)畫延遲執(zhí)行時(shí)間,若想延遲2s寄摆,就設(shè)置CACurrentMediaTime()+2 谅辣,CACurrentMediaTime() 為圖層的 當(dāng)前時(shí)間 |
autoreverses |
動(dòng)畫自動(dòng)逆向執(zhí)行,默認(rèn)為No |
speed |
動(dòng)畫執(zhí)行速度 |
removedOnCompletion |
默認(rèn)為YES婶恼,代表動(dòng)畫執(zhí)行完畢后就從圖層上移除桑阶,圖形會(huì)恢復(fù)到動(dòng)畫執(zhí)行前的狀態(tài)。如果想讓圖層保持顯示動(dòng)畫執(zhí)行后的狀態(tài)熙尉,那就設(shè)置為NO联逻,不過還要設(shè)置fillMode 為kCAFillModeForwards |
fillMode |
決定當(dāng)前對(duì)象在非active時(shí)間段的行為。比如動(dòng)畫開始之前或者動(dòng)畫結(jié)束之后 |
timingFunction |
速度控制函數(shù)检痰,控制動(dòng)畫運(yùn)行的節(jié)奏包归,例:anima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]
|
delegate |
動(dòng)畫代理,監(jiān)聽動(dòng)畫的開始和結(jié)束 |
fillMode
屬性值(要想fillMode
有效铅歼,最好設(shè)置removedOnCompletion
= NO)
kCAFillModeRemoved
這個(gè)是默認(rèn)值公壤,也就是說當(dāng)動(dòng)畫開始前和動(dòng)畫結(jié)束后,動(dòng)畫對(duì)layer都沒有影響椎椰,動(dòng)畫結(jié)束后厦幅,layer會(huì)恢復(fù)到之前的狀態(tài)
CAFillModeForwards
當(dāng)動(dòng)畫結(jié)束后,layer會(huì)一直保持著動(dòng)畫最后的狀態(tài)
kCAFillModeBackwards
在動(dòng)畫開始前慨飘,只需要將動(dòng)畫加入了一個(gè)layer确憨,layer便立即進(jìn)入動(dòng)畫的初始狀態(tài)并等待動(dòng)畫開始。
kCAFillModeBoth
這個(gè)其實(shí)就是上面兩個(gè)的合成.動(dòng)畫加入后開始之前瓤的,layer便處于動(dòng)畫初始狀態(tài)休弃,動(dòng)畫結(jié)束后layer保持動(dòng)畫最后的狀態(tài)
速度控制函數(shù)(CAMediaTimingFunction)
kCAMediaTimingFunctionLinear
(線性):勻速,給你一個(gè)相對(duì)靜態(tài)的感覺
kCAMediaTimingFunctionEaseIn
(漸進(jìn)):動(dòng)畫緩慢進(jìn)入圈膏,然后加速離開
kCAMediaTimingFunctionEaseOut
(漸出):動(dòng)畫全速進(jìn)入塔猾,然后減速的到達(dá)目的地
kCAMediaTimingFunctionEaseInEaseOut
(漸進(jìn)漸出):動(dòng)畫緩慢的進(jìn)入,中間加速稽坤,然后減速的到達(dá)目的地丈甸。這個(gè)是默認(rèn)的動(dòng)畫行為糯俗。
-
delegate
:動(dòng)畫代理@protocol CAAnimationDelegate <NSObject> @optional /* Called when the animation begins its active duration. */ - (void)animationDidStart:(CAAnimation *)anim; /* Called when the animation either completes its active duration or * is removed from the object it is attached to (i.e. the layer). 'flag' * is true if the animation reached the end of its active duration * without being removed. */ - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag; @end
- CALayer上動(dòng)畫的暫停和恢復(fù)
//暫停動(dòng)畫 - (void)pauseLayerAnimation:(CALayer *)layer { CFTimeInterval pauseTimes = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; // speed動(dòng)畫的運(yùn)行速度,當(dāng)為0時(shí)會(huì)停止動(dòng)畫睦擂,speed越大說明動(dòng)畫執(zhí)行速度越快 layer.speed = 0.0; // 讓layer的時(shí)間停留在pauseTimes // 動(dòng)畫的時(shí)間偏移得湘,也就是上次動(dòng)畫的暫停/繼續(xù) 距離本次動(dòng)畫的繼續(xù)/暫停的時(shí)間差 layer.timeOffset = pauseTimes; NSLog(@":pauseTimes:%f", pauseTimes); } //恢復(fù)動(dòng)畫 - (void)resumeLayerAnimation:(CALayer *)layer { CFTimeInterval pauseTimes = layer.timeOffset; //讓CALayer的時(shí)間繼續(xù)行走 layer.speed = 1; // 取消上次記錄的停留時(shí)刻 layer.timeOffset = 0.0; //取消上次設(shè)置的時(shí)間 layer.beginTime = 0.0; CFTimeInterval timeSincePause = CACurrentMediaTime()-pauseTimes; layer.beginTime = timeSincePause; NSLog(@":timeSincePause:%f", timeSincePause); }
2.2 CAPropertyAnimation
CAPropertyAnimation也是一個(gè)抽象類,自身并不能對(duì)layer進(jìn)行動(dòng)畫操作祈匙,需要其子類CABasicAnimation和CAKeyframeAnimation來實(shí)現(xiàn)動(dòng)畫操作忽刽。
屬性解讀
屬性 | 描述 |
---|---|
keyPath |
指定接收層動(dòng)畫的動(dòng)畫類型(詳細(xì)見附錄表) |
cumulative |
下一次動(dòng)畫執(zhí)行是否接著剛才的動(dòng)畫天揖,默認(rèn)為false |
additive |
如何處理多個(gè)動(dòng)畫在同一時(shí)間段執(zhí)行的結(jié)果夺欲,若為true,同一時(shí)間段的動(dòng)畫合成為一個(gè)動(dòng)畫今膊,默認(rèn)為false些阅。(使用 CAKeyframeAnimation 時(shí)必須將該屬性指定為 true ,否則不會(huì)出現(xiàn)期待的結(jié)果) |
2.3 CABasicAnimation——基本動(dòng)畫
基本動(dòng)畫斑唬,是CAPropertyAnimation
的子類
屬性 | 描述 |
---|---|
fromValue |
NSValue類型市埋,keyPath相應(yīng)屬性的初始值 |
toValue |
NSValue類型, keyPath相應(yīng)屬性的結(jié)束值 |
動(dòng)畫過程說明:
隨著動(dòng)畫的進(jìn)行恕刘,在長(zhǎng)度為duration的持續(xù)時(shí)間內(nèi)缤谎,keyPath相應(yīng)屬性的值從fromValue漸漸地變?yōu)閠oValue
keyPath內(nèi)容是CALayer的可動(dòng)畫Animatable屬性
如果fillMode==kCAFillModeForwards同時(shí)removedOnComletion=NO,那么在動(dòng)畫執(zhí)行完畢后褐着,圖層會(huì)保持顯示動(dòng)畫執(zhí)行后的狀態(tài)坷澡。但在實(shí)質(zhì)上,圖層的屬性值還是動(dòng)畫執(zhí)行前的初始值含蓉,并沒有真正被改變频敛。
CABasicAnimation *basicAnim = [CABasicAnimation animation];
basicAnim.keyPath = @"position.y";
basicAnim.fromValue = @(self.redView.layer.position.y);
basicAnim.toValue = @(self.redView.layer.position.y + 300);
basicAnim.duration = 2.0;
// 動(dòng)畫完成時(shí)不移除動(dòng)畫
basicAnim.removedOnCompletion = NO;
// 動(dòng)畫完成時(shí)保持最后的狀態(tài)
basicAnim.fillMode = kCAFillModeForwards;
// 動(dòng)畫重復(fù)次數(shù)
basicAnim.repeatCount = MAXFLOAT;
// 自動(dòng)返轉(zhuǎn)(怎么去,怎么返回)
basicAnim.autoreverses = YES;
// 延遲2S開始動(dòng)畫
basicAnim.beginTime = CACurrentMediaTime()+2;
[self.redView.layer addAnimation:basicAnim forKey:nil];
2.3 CAKeyframeAnimation——關(guān)鍵幀動(dòng)畫
關(guān)鍵幀動(dòng)畫馅扣,也是CAPropertyAnimation
的子類斟赚,與CABasicAnimation
的區(qū)別是:
CABasicAnimation
:只能從一個(gè)數(shù)值(fromValue)變到另一個(gè)數(shù)值(toValue)
CAKeyframeAnimation
:會(huì)使用一個(gè)NSArray保存這些數(shù)值。
屬性 | 描述 |
---|---|
values |
NSArray類型差油,里面的元素(NSValue)稱為“關(guān)鍵幀”(keyframe)拗军。動(dòng)畫對(duì)象會(huì)在指定的時(shí)間(duration)內(nèi),依次顯示values數(shù)組中的每一個(gè)關(guān)鍵幀 |
path |
可以設(shè)置一個(gè)CGPathRef蓄喇、CGMutablePathRef发侵,讓圖層按照路徑軌跡移動(dòng)。path只對(duì)CALayer的anchorPoint和position起作用公罕。如果設(shè)置了path器紧,那么values將被忽略 |
keyTimes |
NSArray類型,可以為對(duì)應(yīng)的關(guān)鍵幀指定對(duì)應(yīng)的時(shí)間點(diǎn)楼眷,其取值范圍為0到1.0铲汪,keyTimes中的每一個(gè)時(shí)間值都對(duì)應(yīng)values中的每一幀熊尉。如果沒有設(shè)置keyTimes,各個(gè)關(guān)鍵幀的時(shí)間是平分的 |
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.iconImageView.center radius:100 startAngle:0 endAngle:M_PI clockwise:YES];
CAKeyframeAnimation *keyFrameAnima = [CAKeyframeAnimation animation];
keyFrameAnima.path = path.CGPath;
keyFrameAnima.keyPath = @"position";
keyFrameAnima.duration = 2;
keyFrameAnima.repeatCount = MAXFLOAT;
keyFrameAnima.autoreverses = YES;
[self.iconImageView.layer addAnimation:keyFrameAnima forKey:nil];
2.4 CAAnimationGroup——?jiǎng)赢嫿M
動(dòng)畫組掌腰,是CAAnimation的子類狰住,可以保存一組動(dòng)畫對(duì)象,將CAAnimationGroup對(duì)象加入層后齿梁,組中所有動(dòng)畫對(duì)象可以同時(shí)并發(fā)運(yùn)行
屬性 | 描述 |
---|---|
animations |
用來保存一組動(dòng)畫對(duì)象的NSArray催植。默認(rèn)情況下,一組動(dòng)畫對(duì)象是同時(shí)運(yùn)行的勺择,也可以通過設(shè)置各個(gè)動(dòng)畫對(duì)象的beginTime屬性來更改動(dòng)畫的開始時(shí)間 |
- (void)addAnimationGrounp {
// 創(chuàng)建一個(gè)基礎(chǔ)動(dòng)畫
CABasicAnimation *basicAnima = [CABasicAnimation animation];
basicAnima.keyPath = @"transform.scale";
basicAnima.fromValue = @1.0;
basicAnima.toValue = @0;
// 創(chuàng)建一個(gè)幀動(dòng)畫
CAKeyframeAnimation *keyframeAnim = [CAKeyframeAnimation animation];
keyframeAnim.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(170, self.redView.center.y) radius:100 startAngle:M_PI endAngle:M_PI*2 clockwise:YES].CGPath;
keyframeAnim.keyPath = @"position";
// 動(dòng)畫組
CAAnimationGroup *animGroup = [CAAnimationGroup animation];
animGroup.animations = @[basicAnima,keyframeAnim];
animGroup.duration = 2.0;
animGroup.repeatCount = MAXFLOAT;
animGroup.autoreverses = YES;
[self.redView.layer addAnimation:animGroup forKey:nil];
}
2.4 CATransition——轉(zhuǎn)場(chǎng)動(dòng)畫
CATransition
是CAAnimation
的子類创南,用于做轉(zhuǎn)場(chǎng)動(dòng)畫,能夠?yàn)閷犹峁┮瞥銎聊缓鸵迫肫聊坏膭?dòng)畫效果省核。UINavigationController就是通過CATransition
實(shí)現(xiàn)了將控制器的視圖推入屏幕的動(dòng)畫效果稿辙。
注意:如果父視圖中的兩個(gè)子視圖互相切換,轉(zhuǎn)場(chǎng)動(dòng)畫應(yīng)加給父視圖气忠!
屬性 | 描述 |
---|---|
type |
動(dòng)畫過渡類型 |
subtype |
動(dòng)畫過渡方向 |
startProgress |
動(dòng)畫起點(diǎn)(在整體動(dòng)畫的百分比) |
endProgress |
動(dòng)畫終點(diǎn)(在整體動(dòng)畫的百分比) |
使用以下public api邻储,如果用了私有api可能會(huì)導(dǎo)致上架問題
//-----------------------------public api------------------------------------
/*
type:
kCATransitionFade; //淡入淡出
kCATransitionMoveIn; //覆蓋
kCATransitionPush; //推擠
kCATransitionReveal; //揭開
/
/
subType:
kCATransitionFromRight;
kCATransitionFromLeft;
kCATransitionFromTop;
kCATransitionFromBottom;
*/
CATransition *transiont = [CATransition animation];
/**
fade , //淡入淡出
push, //推擠
reveal, //揭開
moveIn, //覆蓋
cube, //立方體
suckEffect, //吮吸
oglFlip, //翻轉(zhuǎn)
rippleEffect, //波紋(水滴)
pageCurl, //翻頁
pageUnCurl, //反翻頁
cameraIrisHollowOpen, //開鏡頭
cameraIrisHollowClose, //關(guān)鏡頭
*/
transiont.type =@"pageCurl";
transiont.subtype = @"fromBottom";
transiont.duration = 0.5;
// 動(dòng)畫從哪個(gè)點(diǎn)開始
transiont.startProgress = 0;
// 動(dòng)畫到哪個(gè)點(diǎn)結(jié)束
transiont.endProgress = 0.5;
[self.imageView.layer addAnimation:transiont forKey:nil];
2.5 CASpringAnimation——彈性動(dòng)畫
彈性動(dòng)畫,是CABasicAnimation
的子類
屬性 | 描述 |
---|---|
mass |
質(zhì)量旧噪,質(zhì)量越大吨娜,彈簧的慣性越大 |
stiffness |
彈性系數(shù),彈性系數(shù)越大淘钟,運(yùn)動(dòng)越快 |
damping |
阻尼系數(shù)宦赠,阻尼越大,彈簧的運(yùn)動(dòng)停止越快 |
initialVelocity |
初始速度 |
settlingDuration |
執(zhí)行時(shí)間 |
CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:@"bounds"];
springAnimation.mass = 1;
springAnimation.stiffness = 1000;
springAnimation.damping = 20;
springAnimation.initialVelocity = 50;
springAnimation.duration = springAnimation.settlingDuration;
springAnimation.fromValue = @(self.animationView.bounds);
CGRect newBounds = CGRectMake(self.animationView.bounds.origin.x, self.animationView.bounds.origin.y, self.animationView.bounds.size.width+80, self.animationView.bounds.size.height);
springAnimation.toValue = @(newBounds);
springAnimation.fillMode = kCAFillModeForwards;
springAnimation.removedOnCompletion = NO;
springAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.animationView.layer addAnimation:springAnimation forKey:nil];