CoreAnimation 詳解

CAAnimation:核心動(dòng)畫的基礎(chǔ)類,不能直接使用,負(fù)責(zé)動(dòng)畫運(yùn)行時(shí)間、速度的控制,本身實(shí)現(xiàn)了CAMediaTiming協(xié)議。

CAPropertyAnimation:屬性動(dòng)畫的基類(通過屬性進(jìn)行動(dòng)畫設(shè)置,注意是可動(dòng)畫屬性),不能直接使用。

CAAnimationGroup:動(dòng)畫組,動(dòng)畫組是一種組合模式設(shè)計(jì),可以通過動(dòng)畫組來進(jìn)行所有動(dòng)畫行為的統(tǒng)一控制,組中所有動(dòng)畫效果可以并發(fā)執(zhí)行。

CATransition:轉(zhuǎn)場動(dòng)畫,主要通過濾鏡進(jìn)行動(dòng)畫效果設(shè)置。

CABasicAnimation:基礎(chǔ)動(dòng)畫,通過屬性修改進(jìn)行動(dòng)畫參數(shù)控制,只有初始狀態(tài)和結(jié)束狀態(tài)。

CAKeyframeAnimation:關(guān)鍵幀動(dòng)畫,同樣是通過屬性進(jìn)行動(dòng)畫參數(shù)控制,但是同基礎(chǔ)動(dòng)畫不同的是它可以有多個(gè)狀態(tài)控制。

基礎(chǔ)動(dòng)畫、關(guān)鍵幀動(dòng)畫都屬于屬性動(dòng)畫,就是通過修改屬性值產(chǎn)生動(dòng)畫效果,開發(fā)人員只需要設(shè)置初始值和結(jié)束值,中間的過程動(dòng)畫(又叫“補(bǔ)間動(dòng)畫”)由系統(tǒng)自動(dòng)計(jì)算產(chǎn)生。和基礎(chǔ)動(dòng)畫不同的是關(guān)鍵幀動(dòng)畫可以設(shè)置多個(gè)屬性值,每兩個(gè)屬性中間的補(bǔ)間動(dòng)畫由系統(tǒng)自動(dòng)完成,因此從這個(gè)角度而言基礎(chǔ)動(dòng)畫又可以看成是有兩個(gè)關(guān)鍵幀的關(guān)鍵幀動(dòng)畫。


關(guān)系圖


1.? CABasicAnimation - 基礎(chǔ)動(dòng)畫

下面是個(gè)scale 縮放的例子:

?CABasicAnimation *scaleAnimation = [CABasicAnimation ?

animationWithKeyPath:@"transform.scale"];

// 從1倍放大到1.5倍

scaleAnimation.fromValue = @(1.0);

scaleAnimation.toValue = @(1.5);

//scaleAnimation.beginTime = CACurrentMediaTime()+2; //動(dòng)畫延遲執(zhí)行時(shí)間

scaleAnimation.autoreverses = YES; //設(shè)置這個(gè)屬性表示完成動(dòng)畫后會(huì)回到執(zhí)行動(dòng)畫之前的狀態(tài)

//這兩個(gè)屬性要一起設(shè)置,表示保持執(zhí)行動(dòng)畫后的樣子不變(要想fillMode有效,最好設(shè)置removedOnCompletion=NO)

//scaleAnimation.removedOnCompletion = NO;

//scaleAnimation.fillMode = kCAFillModeForwards;

//重復(fù)次數(shù)

//scaleAnimation.repeatCount = 1;

//動(dòng)畫時(shí)間

scaleAnimation.duration = 0.8;

scaleAnimation.delegate = self; //代理(CAAnimationDelegate)

[self.customView.layer addAnimation:scaleAnimation forKey:@"scaleAnimation"];?

暫停/開始 動(dòng)畫:

-(void)animationPause{

//取得指定圖層動(dòng)畫的媒體時(shí)間,后面參數(shù)用于指定子圖層,這里不需要

CFTimeInterval interval=[self.customView.layer convertTime:CACurrentMediaTime() fromLayer:nil];

//設(shè)置時(shí)間偏移量,保證暫停時(shí)停留在旋轉(zhuǎn)的位置

self.customView.layer.timeOffset = interval;

//速度設(shè)置為0,暫停動(dòng)畫

self.customView.layer.speed=0;

}

-(void)animationResume{

//獲得暫停的時(shí)間

CFTimeInterval beginTime= CACurrentMediaTime()- self.customView.layer.timeOffset;

//設(shè)置偏移量

self.customView.layer.timeOffset=0;

//設(shè)置開始時(shí)間

self.customView.layer.beginTime=beginTime;

//設(shè)置動(dòng)畫速度,開始運(yùn)動(dòng)

self.customView.layer.speed=1.0;

}

代理就兩個(gè)回調(diào):

- (void)animationDidStart:(CAAnimation *)anim;

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;

解釋下 fillMode 屬性以及 "animationWithKeyPath:" 這個(gè)字符串參數(shù):

fillMode 有這四個(gè)類型:

/**

kCAFillModeRemoved 這個(gè)是默認(rèn)值,也就是說當(dāng)動(dòng)畫開始前和動(dòng)畫結(jié)束后,動(dòng)畫對layer都沒有影響,動(dòng)畫結(jié)束后,layer會(huì)恢復(fù)到之前的狀態(tài)?.

kCAFillModeForwards 當(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)畫開始. 你可以這樣設(shè)定測試代碼,將一個(gè)動(dòng)畫加入一個(gè)layer的時(shí)候延遲5秒執(zhí)行.然后就會(huì)發(fā)現(xiàn)在動(dòng)畫沒有開始的時(shí)候,只要?jiǎng)赢嫳患尤肓薼ayer,layer便處于動(dòng)畫初始狀態(tài) ( 這里表示不是很理解)

kCAFillModeBoth 這個(gè)其實(shí)就是上面兩個(gè)的合成.動(dòng)畫加入后開始之前,layer便處于動(dòng)畫初始狀態(tài),動(dòng)畫結(jié)束后layer保持動(dòng)畫最后的狀

*/

"animationWithKeyPath:" ?傳的參數(shù)不能錯(cuò),比如上面的例子是縮放,就要寫? "transform.scale",如果想要設(shè)置水平或者上下移動(dòng)就需要 "transform.translation.x"或者 "transform.translation.y"

具體參照下圖:

可設(shè)置的屬性-1


2.CAAimationGroup - ?動(dòng)畫組合

相比于CABasicAnimation 就多了一個(gè) 用來存放動(dòng)畫對象的 animations ?數(shù)組屬性。

?下面是一個(gè)縮放平移繞y軸旋轉(zhuǎn)的組合動(dòng)畫:

CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

scaleAnimation.fromValue = @(1);

scaleAnimation.toValue = @(0.5);

scaleAnimation.autoreverses = YES;

CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];

moveAnimation.fromValue = @(0);

moveAnimation.toValue = @(100);

moveAnimation.autoreverses = YES;

CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];

rotateAnimation.fromValue = @(0);

rotateAnimation.toValue = @(2*M_PI);

rotateAnimation.autoreverses = YES;

CAAnimationGroup *groupAnnimation = [CAAnimationGroup animation];

groupAnnimation.duration = 2;

groupAnnimation.autoreverses = YES;

groupAnnimation.animations = @[moveAnimation, scaleAnimation, rotateAnimation];

groupAnnimation.repeatCount = MAXFLOAT;

[self.customView.layer addAnimation:groupAnnimation forKey:@"groupAnnimation"];


3.CAKeyframeAnimation - 關(guān)鍵幀動(dòng)畫?

下面是一個(gè)利用? CAKeyframeAnimation 改變View 背景色的 小例子:

CAKeyframeAnimation *color = [CAKeyframeAnimation animationWithKeyPath:@"backgroundColor"];

color.values = @[(id)[UIColor redColor].CGColor,(id)[UIColor yellowColor].CGColor,(id)[UIColor blueColor].CGColor];

color.keyTimes = @[@0, @0.4,@0.6, @0.8,@1.1];

color.repeatCount = 1;

color.autoreverses = YES;

color.duration = 3;

[self.customView.layer addAnimation:color forKey:@"color"];

簡單的介紹下常用的屬性:

values:就是上述的NSArray對象。里面的元素稱為”關(guān)鍵幀”(keyframe)。動(dòng)畫對象會(huì)在指定的時(shí)間(duration)內(nèi),依次顯示values數(shù)組中的每一個(gè)關(guān)鍵幀 .

keyTimes:各個(gè)關(guān)鍵幀的時(shí)間控制。

path:可以設(shè)置一個(gè)CGPathRef\CGMutablePathRef,讓層跟著路徑移動(dòng)。path只對CALayer的anchorPoint和position起作用。如果你設(shè)置了path,那么values將被忽略 。

timingFunctions: 這個(gè)屬性用以指定時(shí)間函數(shù),類似于運(yùn)動(dòng)的加速度。

(1) kCAMediaTimingFunctionLinear//線性

(2) kCAMediaTimingFunctionEaseIn//淡入

(3) kCAMediaTimingFunctionEaseOut//淡出

(4) kCAMediaTimingFunctionEaseInEaseOut//淡入淡出

(5) kCAMediaTimingFunctionDefault//默認(rèn)

calculationMode: 該屬性決定了物體在每個(gè)子路徑下是跳著走還是勻速走。

(1) const kCAAnimationLinear//線性,默認(rèn)

(2) const kCAAnimationDiscrete//離散,無中間過程,但keyTimes設(shè)置的時(shí)間依舊生效,物體跳躍地出現(xiàn)在各個(gè)關(guān)鍵幀上

(3) const kCAAnimationPaced//平均,keyTimes跟timeFunctions失效

(4) const kCAAnimationCubic//平均,同上

(5) const kCAAnimationCubicPaced//平均,同上

下面這個(gè)是 CAKeyframeAnimation 配合貝塞爾曲線 的簡單例子:?

CAKeyframeAnimation *keyframeAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];

//2.設(shè)置路徑

//繪制貝塞爾曲線

UIBezierPath *path = [[UIBezierPath alloc] init];

[path moveToPoint:CGPointMake(self.customView.layer.position.x, self.customView.layer.position.y)];

[path addCurveToPoint:CGPointMake(55, 400) controlPoint1:CGPointMake(10, 300) controlPoint2:CGPointMake(160, 280)];

keyframeAnimation.path=path.CGPath;//設(shè)置path屬性

//設(shè)置其他屬性

keyframeAnimation.duration=8.0;

keyframeAnimation.beginTime=CACurrentMediaTime();//設(shè)置延遲2秒執(zhí)行

keyframeAnimation.removedOnCompletion = NO;

keyframeAnimation.fillMode = kCAFillModeForwards;

//3.添加動(dòng)畫到圖層,添加動(dòng)畫后就會(huì)執(zhí)行動(dòng)畫

[self.customView.layer addAnimation:keyframeAnimation forKey:@"KCKeyframeAnimation_Position"];

4. CATransition - 轉(zhuǎn)場動(dòng)畫

簡單的例子:

CATransition *transition = [CATransition animation];

transition.duration = 2.0f;

transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

transition.type = kCATransitionMoveIn;

transition.subtype = kCATransitionFromRight;

[self.customView.layer addAnimation:transition forKey:@"animation"];

簡單的介紹下 幾個(gè)屬性:

type?: 有四種類型:

kCATransitionFade? ? ? ? ? ? ? ? ? //交叉淡化過渡

kCATransitionMoveIn? ? ? ? ? ? ? //移動(dòng)覆蓋原圖

kCATransitionPush? ? ? ? ? ? ? ? ? ? //新視圖將舊視圖推出去

kCATransitionReveal? ? ? ? ? ? ? ? //底部顯出來

subType: 同樣四種

kCATransitionFromRight;

kCATransitionFromLeft(默認(rèn)值)

kCATransitionFromTop;

kCATransitionFromBottom


參考鏈接: http://www.cnblogs.com/wengzilin/p/4256468.html

? ? ? ? ? ? ? http://www.bubuko.com/infodetail-1000965.html

? ? ? ? ? ? ? http://www.cocoachina.com/ios/20141022/10005.html

? ? ? ? ? ? ? http://www.cnblogs.com/wengzilin/p/4250957.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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