- 我所知道的Core Animation
- Core Animation負(fù)責(zé)所有的滾動、旋轉(zhuǎn)、縮小和放大以及所有的iOS動畫效果。其中UIKit類通常都有animated:參數(shù)部分,它可以允許是否使用動畫。
- Core Animation的動畫執(zhí)行過程都是在后臺操作的,不會阻塞主線程。不阻塞主線程,可以理解為在執(zhí)行動畫的時候還能點擊(按鈕)。用圖形處理硬件操縱位圖要比圖形處理軟件能獲得更好的動畫效果。因為操縱的是靜態(tài)的位圖,基于圖層的繪圖和基于視圖的繪圖在技術(shù)上有明顯的不同。對基于視圖的繪圖,對視圖的改變經(jīng)常會觸發(fā)調(diào)用視圖的drawRect:方法以重繪視圖內(nèi)容。但是此種方式的代價相對較高,因為它是CPU在主線程上的操作。Core Animation通過盡可能的使用圖形硬件操縱緩存后的位圖來避免了這種開銷,從而完成相同或相似的效果。
-
Core Animation還與Quartz緊密結(jié)合在一起,每個UIView都關(guān)聯(lián)到一個CALayer對象,CALayer是Core Animation中的圖層。要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。
圖1-iOS圖形層關(guān)系
- 核心動畫類有一下分類:
①提供顯示內(nèi)容的圖層類:CALayer
②動畫和計時類:Animation and Timing Classes
③布局和約束類:CAConstraint
④事物類,在原子更新的時候組合圖層類。核心動畫的基礎(chǔ)類包含在 Quartz核心框架(Quartz Core framework)里面,雖然它的其他圖層類在其他圖層類在其他框架里面定義。(CATransaction)
-
CAlayer層的屬性
(1)、position和anchorPoint
CALayer有2個非常重要的屬性:position和anchorPoint
圖2 -AnchorPoint
@property CGPoint position;
用來設(shè)置CALayer在父層中的位置,以父層的左上角為原點(0, 0)
@property CGPoint anchorPoint;
稱為“定位點”、“錨點”決定著CALayer身上的哪個點會在position屬性所指的位置,以自己的左上角為原點(0, 0),它的x、y取值范圍都是0~1,默認(rèn)值為(0.5, 0.5)
(2)、隱式動畫
每一個UIView內(nèi)部都默認(rèn)關(guān)聯(lián)著一個CALayer,我們可用稱這個Layer為Root Layer(根層)所有的非Root Layer,也就是手動創(chuàng)建的CALayer對象,都存在著隱式動畫
什么是隱式動畫?
當(dāng)對非Root Layer的部分屬性進行修改時,默認(rèn)會自動產(chǎn)生一些動畫效果
而這些屬性稱為Animatable Properties(可動畫屬性)
列舉幾個常見的Animatable Properties:
bounds:用于設(shè)置CALayer的寬度和高度。修改這個屬性會產(chǎn)生縮放動畫
backgroundColor:用于設(shè)置CALayer的背景色。修改這個屬性會產(chǎn)生背景色的漸變動畫
position:用于設(shè)置CALayer的位置。修改這個屬性會產(chǎn)生平移動畫
-
CAAnimation (動畫類)
CAAnimation是所有動畫類的父類,但是它不能直接使用,應(yīng)該使用它的子類。
圖3-CAAnimation類的繼承結(jié)構(gòu)圖
常見屬性有:
duration:動畫的持續(xù)時間
repeatCount:動畫的重復(fù)次數(shù)
repeatDuration:動畫的重復(fù)時間
timingFunction:控制動畫運行的節(jié)奏
fillMode:決定當(dāng)前對象在非active時間段的行為.比如動畫開始之前,動畫結(jié)束之后
beginTime:可以用來設(shè)置動畫延遲執(zhí)行時間,若想延遲2s,就設(shè)置為CACurrentMediaTime()+2,CACurrentMediaTime()為圖層的當(dāng)前時間
類的說明:
(1)能用的動畫類只有4個子類:CABasicAnimation、CAKeyframeAnimation、CATransition、CAAnimationGroup
①CABasicAnimation
通過設(shè)定起始點,終點,時間,動畫會沿著你這設(shè)定點進行移動??梢钥醋鎏厥獾腃AKeyFrameAnimation
②CAKeyframeAnimation
Keyframe顧名思義就是關(guān)鍵點的frame,你可以通過設(shè)定CALayer的始點、中間關(guān)鍵點、終點的frame,時間,動畫會沿你設(shè)定的軌跡進行移動
③CAAnimationGroup
Group也就是組合的意思,就是把對這個Layer的所有動畫都組合起來。PS:一個layer設(shè)定了很多動畫,他們都會同時執(zhí)行,如何按順序執(zhí)行我到時候再講。
④CATransition
這個就是蘋果幫開發(fā)者封裝好的一些動畫
(2)CAMediaTiming是一個協(xié)議(protocol)。
CAPropertyAnimation是CAAnimation的子類,但是不能直接使用,要想創(chuàng)建動畫對象,應(yīng)該使用它的兩個子類:CABasicAnimation和CAKeyframeAnimation。
它有個NSString類型的keyPath屬性,你可以指定CALayer的某個屬性名為keyPath,并且對CALayer的這個屬性的值進行修改,達到相應(yīng)的動畫效果。比如,指定@"position"為keyPath,就會修改CALayer的position屬性的值,以達到平移的動畫效果
-
Core Animation的使用步驟
1.使用它需要先添加QuartzCore.framework框架和引入主頭文件<QuartzCore/QuartzCore.h>(iOS7不需要)
2.初始化一個CAAnimation對象,并設(shè)置一些動畫相關(guān)屬性
3.通過調(diào)用CALayer的addAnimation:forKey:方法增加CAAnimation對象到CALayer中,這樣就能開始執(zhí)行動畫了
4.通過調(diào)用CALayer的removeAnimationForKey:方法可以停止CALayer中的動畫
圖4-基于圖層的動畫
補充一下animationWithKeyPath值的總結(jié):

- OC中的動畫效果
視圖動畫、幀動畫 - 三個問題
1.什么事圖層CALayer?
核心動畫的所有效果都是基于圖層的,沒有圖層也就沒有核心動畫效果
2.視圖什么時候能夠顯示在屏幕上?
1)調(diào)用drawRect方法,如果我們自己繪制了東西,他會顯示出來
2)在顯示圖形之前他會創(chuàng)建一個圖層對象(CALayer),然后把需要的東西都放在圖層上,然后呈現(xiàn)給用戶看
3)沒有圖層就沒有視圖的顯示功能,也就是沒有界面
3.圖層能夠用來做什么?
1)陰影效果
2)邊框效果
3)圓角效果
4)更強大的動畫效果
本篇核心動畫有以下幾點內(nèi)容:
1.核心動畫基礎(chǔ)知識
2.有關(guān)錨點
3.隱式動畫
4.自定義圖層
5.CAAnimation
其中CAAnimation又有以下幾點小內(nèi)容:
1.位移
2.縮放
3.透明度
4.旋轉(zhuǎn)
5.組合動畫
6.繞矩形環(huán)跑
示例

//實例1:(位移)以position作為參考點來執(zhí)行動畫的
-(void)WeiYi{
//創(chuàng)建基礎(chǔ)動畫
CABasicAnimation *ban = [CABasicAnimation animation];
//設(shè)置動畫路徑
//從什么值開始,因為fromValue是個id類型,所以把起點point包裝成NSValue傳遞給他
//錨點的位置(如果不寫fromValue,代表從當(dāng)前位置開始變)
ban.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
//變化到什么值結(jié)束
ban.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 500)];
//設(shè)置動畫對象
//keyPath 決定了執(zhí)行怎樣的動畫
//使用kvc的方式來告訴動畫,要使用layer的哪個屬性變動來完成動畫效果
// NSString *keyPath = @"position";
//
// [self.layer addAnimation:ban forKey:keyPath];
//沒起作用,因為是在動畫添加到layer之后的屬性,所以沒有起作用
ban.duration = 3.0;
//當(dāng)動畫執(zhí)行完成后,還會回到最初的位置,這是核心動畫的特點
//禁止歸位,執(zhí)行完動畫之后移除動畫效果
//注意這量兩個屬性,要改變核心動畫的屬性,必須都添加到layer之前,否則無效
//動畫完成后不刪除
ban.removedOnCompletion = NO;
//保持最新的狀態(tài)
ban.fillMode = kCAFillModeForwards;
NSString *keyPath = @"position";
[self.layer addAnimation:ban forKey:keyPath];
}
//實例2:縮放屬性
-(void)SuoFang{
CABasicAnimation *ban = [CABasicAnimation animation];
ban.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.5, 1.5, 1)];
ban.duration = 1.0;
// self.layer.transform =
// transform.scale表示等比例拉伸
// transform按照參數(shù)比例拉伸
ban.keyPath = @"transform";
//執(zhí)行完動畫不刪除動畫
ban.removedOnCompletion = NO;
//保持最新狀態(tài)
ban.fillMode = kCAFillModeForwards;
//如果通過keyPath設(shè)置了屬性,后面的參數(shù)可以傳nil
[self.layer addAnimation:ban forKey:nil];
}
//實例3:透明度屬性
- (void)TouMingDu{
//初始化的時候就定制好動畫類型
CABasicAnimation *ban = [CABasicAnimation animationWithKeyPath:@"opacity"];
//透明度是float類型
ban.fromValue = [NSNumber numberWithFloat:1.0];
ban.toValue = [NSNumber numberWithFloat:0.1];
ban.duration = 3.0;
ban.removedOnCompletion = NO;
ban.fillMode = kCAFillModeForwards;
[self.layer addAnimation:ban forKey:nil];
}
//實例4:旋轉(zhuǎn)屬性
- (void)XuanZhuan{
CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnima.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
//CATransform3DIdentity 是單位矩陣,該矩陣沒有縮放、旋轉(zhuǎn)、歪斜、透視。把該矩陣應(yīng)用到圖層上面會把圖層幾何屬性修改為默認(rèn)值
//沿著Z軸旋轉(zhuǎn)
transformAnima.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2, 0, 0, 1)];
//旋轉(zhuǎn)效果累計(即下一次動畫執(zhí)行是否接著剛才的動畫)
transformAnima.cumulative = YES;
//旋轉(zhuǎn)2遍
transformAnima.repeatCount = 2;
transformAnima.duration = 3.0;
[self.layer addAnimation:transformAnima forKey:nil];
}
//實例6:組合動畫CAAnimationGroup
-(void)ZuHeAnimation{
CAAnimationGroup *animGroup = [CAAnimationGroup animation];
//縮放
CABasicAnimation *banScale = [CABasicAnimation animation];
banScale.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1, 1.5, 1)];
banScale.duration = 3.0;
banScale.keyPath = @"transform";
banScale.removedOnCompletion = NO;
banScale.fillMode = kCAFillModeForwards;
//透明
CABasicAnimation *banOpacity = [CABasicAnimation animationWithKeyPath:@"opacity"];
banOpacity.fromValue = [NSNumber numberWithFloat:1.0];
banOpacity.toValue = [NSNumber numberWithFloat:0.1];
banOpacity.duration = 3.0;
banOpacity.removedOnCompletion = NO;
banOpacity.fillMode = kCAFillModeForwards;
//旋轉(zhuǎn)
CABasicAnimation *transformAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnim.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
transformAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 0, 0, 1)];
transformAnim.cumulative = YES;
transformAnim.repeatCount = 2;
transformAnim.duration = 2.0;
animGroup.animations = [NSArray arrayWithObjects:self.pathAnimation, banScale, banOpacity, transformAnim, nil];
animGroup.duration = 5.0;
[self.layer addAnimation:animGroup forKey:nil];
}
//CAKeyframeAnimation
//CABasicAnimation算是CAKeyFrameAnimation的特殊情況,即不考慮中間變換過程,只考慮起始點與目標(biāo)點就可以了。而CAKeyFrameAnimation則更復(fù)雜一些,允許我們在起點與終點間自定義更多內(nèi)容來達到我們的實際應(yīng)用需求,KeyFrame的意思是關(guān)鍵幀,所謂“關(guān)鍵”就是改變物體運動趨勢的幀,在該點處物體將發(fā)生運動狀態(tài),比如矩形的四個角,拋物線的頂點等
-(CAAnimation*)pathAnimation{
/**
CAKeyframeAnimation
在畫線的時候,方法的內(nèi)部默認(rèn)創(chuàng)建一個path。它把路徑都放到了path里面去。
1.創(chuàng)建路徑 CGMutablePathRef 調(diào)用該方法相當(dāng)于創(chuàng)建了一個路徑,這個路徑用來保存繪圖信息。
2.把繪圖信息添加到路徑里邊。
以前的方法是點的位置添加到ctx(圖形上下文信息)中,ctx 默認(rèn)會在內(nèi)部創(chuàng)建一個path用來保存繪圖信息。
在圖形上下文中有一塊存儲空間專門用來存儲繪圖信息,其實這塊空間就是CGMutablePathRef。
3.把路徑添加到上下文中。
*/
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path,NULL,50.0,120.0);
CGPathAddLineToPoint(path, NULL, 300, 488);
CGPathAddCurveToPoint(path,NULL,50.0,275.0,150.0,275.0,150.0,120.0);
CGPathAddCurveToPoint(path,NULL,150.0,275.0,250.0,275.0,250.0,120.0);
CGPathAddCurveToPoint(path,NULL,250.0,275.0,350.0,275.0,350.0,120.0);
CGPathAddCurveToPoint(path,NULL,350.0,275.0,450.0,275.0,450.0,120.0);
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
[animation setPath:path];
[animation setDuration:3.0];
CFRelease(path);
//ARC的誕生大大簡化了我們針對內(nèi)存管理的開發(fā)工作,但是只支持管理 Objective-C 對象, 不支持 Core Foundation 對象。Core Foundation 對象必須使用CFRetain和CFRelease來進行內(nèi)存管理
//http://blog.csdn.net/yiyaaixuexi/article/details/8553659
return animation;
}
//繞矩形環(huán)跑
- (void)RectRun{
//新處理一下self.layer
self.layer.frame = CGRectMake(15, 200, 30, 30);
self.layer.cornerRadius = 15;
self.layer.masksToBounds = YES;
//來個幀動畫
CAKeyframeAnimation *rectRunAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//設(shè)定關(guān)鍵幀位置,必須含起始和終止位置
rectRunAnimation.values = @[[NSValue valueWithCGPoint:self.layer.frame.origin],
[NSValue valueWithCGPoint:CGPointMake(320-15, self.layer.frame.origin.y)],
[NSValue valueWithCGPoint:CGPointMake(320-15, self.layer.frame.origin.y+100)],
[NSValue valueWithCGPoint:CGPointMake(15, self.layer.frame.origin.y+100)],
[NSValue valueWithCGPoint:self.layer.frame.origin]];
//設(shè)定每個關(guān)鍵幀的時長,如果沒有顯示的設(shè)置,則默認(rèn)每個幀的時間=總duration/(values.count - 1)
rectRunAnimation.keyTimes = @[[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:0.6],
[NSNumber numberWithFloat:0.7],
[NSNumber numberWithFloat:0.8],
[NSNumber numberWithFloat:1]];
rectRunAnimation.timingFunctions = @[
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
//重復(fù)次數(shù)
rectRunAnimation.repeatCount = 10;
//動畫結(jié)束是否執(zhí)行逆動畫
rectRunAnimation.autoreverses = NO;
//線性運動方式
rectRunAnimation.calculationMode = kCAAnimationLinear;
//持續(xù)時間
rectRunAnimation.repeatDuration = 4;
//添加動畫
[self.layer addAnimation:rectRunAnimation forKey:@"rectRunAnimation"];
/**
CAKeyFrameAnimation的使用中有以下主要的屬性需要注意
(1)values屬性
values屬性指明整個動畫過程中的關(guān)鍵幀點,例如上例中的A-E就是通過values指定的。需要注意的是,起點必須作為values的第一個值。
(2)path屬性
作用與values屬性一樣,同樣是用于指定整個動畫所經(jīng)過的路徑的。需要注意的是,values與path是互斥的,當(dāng)values與path同時指定時,path會覆蓋values,即values屬性將被忽略。例如上述pathAnimation例子
(3)keyTimes屬性
該屬性是一個數(shù)組,用以指定每個子路徑(AB,BC,CD)的時間。如果你沒有顯式地對keyTimes進行設(shè)置,則系統(tǒng)會默認(rèn)每條子路徑的時間為:ti=duration/(5-1),即每條子路徑的duration相等,都為duration的1\4。當(dāng)然,我們也可以傳個數(shù)組讓物體快慢結(jié)合。例如,你可以傳入{0.0, 0.1,0.6,0.7,1.0},其中首尾必須分別是0和1,因此tAB=0.1-0, tCB=0.6-0.1, tDC=0.7-0.6, tED=1-0.7.....
(4)timeFunctions屬性
用過UIKit層動畫的同學(xué)應(yīng)該對這個屬性不陌生,這個屬性用以指定時間函數(shù),類似于運動的加速度,有以下幾種類型。上例子的AB段就是用了淡入淡出效果。記住,這是一個數(shù)組,你有幾個子路徑就應(yīng)該傳入幾個元素
1 kCAMediaTimingFunctionLinear//線性
2 kCAMediaTimingFunctionEaseIn//淡入
3 kCAMediaTimingFunctionEaseOut//淡出
4 kCAMediaTimingFunctionEaseInEaseOut//淡入淡出
5 kCAMediaTimingFunctionDefault//默認(rèn)
(5)calculationMode屬性
該屬性決定了物體在每個子路徑下是跳著走還是勻速走,跟timeFunctions屬性有點類似
1 const kCAAnimationLinear//線性,默認(rèn)
2 const kCAAnimationDiscrete//離散,無中間過程,但keyTimes設(shè)置的時間依舊生效,物體跳躍地出現(xiàn)在各個關(guān)鍵幀上
3 const kCAAnimationPaced//平均,keyTimes跟timeFunctions失效
4 const kCAAnimationCubic//平均,同上
5 const kCAAnimationCubicPaced//平均,同上
*/
}
代碼地址:https://github.com/SPIREJ/SJCoreAnimation
https://www.cnblogs.com/bucengyongyou/archive/2012/12/20/2826590.html



