CALayer
- 在iOS中,你能看得見摸得著的東西基本上都是UIView蹋盆,比如一個(gè)按鈕、一個(gè)文本標(biāo)簽硝全、一個(gè)文本輸入框栖雾、一個(gè)圖標(biāo)等等,這些都是UIView
- 其實(shí)UIView之所以能顯示在屏幕上伟众,完全是因?yàn)樗鼉?nèi)部的一個(gè)圖層
- 在創(chuàng)建UIView對(duì)象時(shí)析藕,UIView內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)圖層(即CALayer對(duì)象),通過UIView的layer屬性可以訪問這個(gè)層
@property(nonatomic,readonly,retain) CALayer *layer;
- 當(dāng)UIView需要顯示到屏幕上時(shí)凳厢,會(huì)調(diào)用drawRect:方法進(jìn)行繪圖账胧,并且會(huì)將所有內(nèi)容繪制在自己的圖層上竞慢,繪圖完畢后,系統(tǒng)會(huì)將圖層拷貝到屏幕上治泥,于是就完成了UIView的顯示
- 換句話說筹煮,UIView本身不具備顯示的功能,是它內(nèi)部的層才有顯示功能
CALayer的基本使用
- 通過操作CALayer對(duì)象居夹,可以很方便地調(diào)整UIView的一些外觀屬性败潦,比如:
- 陰影
- 圓角大小
- 邊框?qū)挾群皖伾?/p>
… …
還可以給圖層添加動(dòng)畫,來實(shí)現(xiàn)一些比較炫酷的效果
CALayer的屬性
// 寬度和高度
@property CGRect bounds;
// 位置(默認(rèn)指中點(diǎn)吮播,具體由anchorPoint決定)
@property CGPoint position;
// 錨點(diǎn)(x,y的范圍都是0-1)变屁,決定了position的含義
@property CGPoint anchorPoint;
// 背景顏色(CGColorRef類型)
@property CGColorRef backgroundColor;
// 形變屬性
@property CATransform3D transform;
// 寬度和高度
@property CGRect bounds;
// 位置(默認(rèn)指中點(diǎn),具體由anchorPoint決定)
@property CGPoint position;
// 錨點(diǎn)(x,y的范圍都是0-1)意狠,決定了position的含義
@property CGPoint anchorPoint;
// 背景顏色(CGColorRef類型)
@property CGColorRef backgroundColor;
// 形變屬性
@property CATransform3D transform;
?x\y\z軸
關(guān)于CALayer的疑惑
- 首先
- CALayer是定義在QuartzCore框架中的
- CGImageRef粟关、CGColorRef兩種數(shù)據(jù)類型是定義在CoreGraphics框架中的
- UIColor、UIImage是定義在UIKit框架中的
- 其次
- QuartzCore框架和CoreGraphics框架是可以跨平臺(tái)使用的环戈,在iOS和Mac OS X上都能使用
- 但是UIKit只能在iOS中使用
- 為了保證可移植性闷板,QuartzCore不能使用UIImage、UIColor院塞,只能使用CGImageRef遮晚、CGColorRef
UIView和CALayer的選擇
- 通過CALayer,就能做出跟UIImageView一樣的界面效果
- 既然CALayer和UIView都能實(shí)現(xiàn)相同的顯示效果拦止,那究竟該選擇誰好呢县遣?
- 其實(shí),對(duì)比CALayer汹族,UIView多了一個(gè)事件處理的功能萧求。也就是說,CALayer不能處理用戶的觸摸事件顶瞒,而UIView可以
- 所以夸政,如果顯示出來的東西需要跟用戶進(jìn)行交互的話,用UIView榴徐;如果不需要跟用戶進(jìn)行交互守问,用UIView或者CALayer都可以
- 當(dāng)然,CALayer的性能會(huì)高一些坑资,因?yàn)樗倭耸录幚淼墓δ芎呐粒虞p量級(jí)
position和anchorPoint
- CALayer有2個(gè)非常重要的屬性:position和anchorPoint
- @property CGPoint position;
- 用來設(shè)置CALayer在父層中的位置
- 以父層的左上角為原點(diǎn)(0, 0)
- @property CGPoint anchorPoint;
- 稱為“定位點(diǎn)”、“錨點(diǎn)”
- 決定著CALayer身上的哪個(gè)點(diǎn)會(huì)在position屬性所指的位置
- 以自己的左上角為原點(diǎn)(0, 0)
- 它的x袱贮、y取值范圍都是0~1仿便,默認(rèn)值為(0.5, 0.5)
anchorPoint(示意圖)
position和anchorPoint
隱式動(dòng)畫
- 每一個(gè)UIView內(nèi)部都默認(rèn)關(guān)聯(lián)著一個(gè)CALayer,我們可用稱這個(gè)Layer為Root Layer(根層)
- 所有的非Root Layer,也就是手動(dòng)創(chuàng)建的CALayer對(duì)象探越,都存在著隱式動(dòng)畫
- 什么是隱式動(dòng)畫?
- 當(dāng)對(duì)非Root Layer的部分屬性進(jìn)行修改時(shí)窑业,默認(rèn)會(huì)自動(dòng)產(chǎn)生一些動(dòng)畫效果
- 而這些屬性稱為Animatable Properties(可動(dòng)畫屬性)
- 列舉幾個(gè)常見的Animatable Properties:
- bounds:用于設(shè)置CALayer的寬度和高度钦幔。修改這個(gè)屬性會(huì)產(chǎn)生縮放動(dòng)畫
- backgroundColor:用于設(shè)置CALayer的背景色。修改這個(gè)屬性會(huì)產(chǎn)生背景色的漸變動(dòng)畫
- position:用于設(shè)置CALayer的位置常柄。修改這個(gè)屬性會(huì)產(chǎn)生平移動(dòng)畫
- 可以通過動(dòng)畫事務(wù)(CATransaction)關(guān)閉默認(rèn)的隱式動(dòng)畫效果
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.myview.layer.position = CGPointMake(10, 10);
[CATransaction commit];
核心動(dòng)畫
Core Animation簡介
- Core Animation鲤氢,中文翻譯為核心動(dòng)畫,它是一組非常強(qiáng)大的動(dòng)畫處理API西潘,使用它能做出非常炫麗的動(dòng)畫效果卷玉,而且往往是事半功倍。也就是說喷市,使用少量的代碼就可以實(shí)現(xiàn)非常強(qiáng)大的功能相种。
-? Core Animation可以用在Mac OS X和iOS平臺(tái)。
-? Core Animation的動(dòng)畫執(zhí)行過程都是在后臺(tái)操作的品姓,不會(huì)阻塞主線程寝并。
-? 要注意的是,Core Animation是直接作用在CALayer上的腹备,并非UIView衬潦。
核心動(dòng)畫繼承結(jié)構(gòu)
Core Animation的使用步驟
- 如果不是xcode5之后的版本,使用它需要先添加QuartzCore.framework和引入對(duì)應(yīng)的框架- 開發(fā)步驟:
- 1.首先得有CALayer
- 2.初始化一個(gè)CAAnimation對(duì)象植酥,并設(shè)置一些動(dòng)畫相關(guān)屬性
- 3.通過調(diào)用CALayer的addAnimation:forKey:方法镀岛,增加CAAnimation對(duì)象到CALayer中,這樣就能開始執(zhí)行動(dòng)畫了
- 4.通過調(diào)用CALayer的removeAnimationForKey:方法可以停止CALayer中的動(dòng)畫
CAAnimation——簡介
- 是所有動(dòng)畫對(duì)象的父類友驮,負(fù)責(zé)控制動(dòng)畫的持續(xù)時(shí)間和速度漂羊,是個(gè)抽象類,不能直接使用喊儡,應(yīng)該使用它具體的子類
- 屬性說明:(紅色代表來自CAMediaTiming協(xié)議的屬性)
- duration:動(dòng)畫的持續(xù)時(shí)間
- repeatCount:重復(fù)次數(shù)拨与,無限循環(huán)可以設(shè)置HUGE_VALF或者M(jìn)AXFLOAT
- repeatDuration:重復(fù)時(shí)間
- removedOnCompletion:默認(rèn)為YES,代表動(dòng)畫執(zhí)行完畢后就從圖層上移除艾猜,圖形會(huì)恢復(fù)到動(dòng)畫執(zhí)行前的狀態(tài)买喧。如果想讓圖層保持顯示動(dòng)畫執(zhí)行后的狀態(tài),那就設(shè)置為NO匆赃,不過還要設(shè)置fillMode為k? - CAFillModeForwards
- fillMode:決定當(dāng)前對(duì)象在非active時(shí)間段的行為淤毛。比如動(dòng)畫開始之前或者動(dòng)畫結(jié)束之后
- beginTime:可以用來設(shè)置動(dòng)畫延遲執(zhí)行時(shí)間,若想延遲2s算柳,就設(shè)置為CACurrentMediaTime()+2低淡,CACurrentMediaTime()為圖層的當(dāng)前時(shí)間
- timingFunction:速度控制函數(shù),控制動(dòng)畫運(yùn)行的節(jié)奏
- delegate:動(dòng)畫代理
CAAnimation——?jiǎng)赢嬏畛淠J?/h4>
- fill Mode屬性值(要想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)
- 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)畫開始戒傻。
- kCAFillModeBoth 這個(gè)其實(shí)就是上面兩個(gè)的合成.動(dòng)畫加入后開始之前,layer便處于動(dòng)畫初始狀態(tài)蜂筹,動(dòng)畫結(jié)束后layer保持動(dòng)畫最后的狀態(tài)
CAAnimation——速度控制函數(shù)
- fill Mode屬性值(要想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)
- 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)畫開始戒傻。
- 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)畫行為
CAAnimation——?jiǎng)赢嫶矸椒?/h4>
- CAAnimation在分類中定義了代理方法
@interface NSObject (CAAnimationDelegate)
/* 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ù)
#pragma mark 暫停CALayer的動(dòng)畫
-(void)pauseLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
// 讓CALayer的時(shí)間停止走動(dòng)
layer.speed = 0.0;
// 讓CALayer的時(shí)間停留在pausedTime這個(gè)時(shí)刻
layer.timeOffset = pausedTime;
}
#pragma mark 恢復(fù)CALayer的動(dòng)畫
-(void)resumeLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = layer.timeOffset;
// 1. 讓CALayer的時(shí)間繼續(xù)行走
layer.speed = 1.0;
// 2. 取消上次記錄的停留時(shí)刻
layer.timeOffset = 0.0;
// 3. 取消上次設(shè)置的時(shí)間
layer.beginTime = 0.0;
// 4. 計(jì)算暫停的時(shí)間(這里也可以用CACurrentMediaTime()-pausedTime)
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
// 5. 設(shè)置相對(duì)于父坐標(biāo)系的開始時(shí)間(往后退timeSincePause)
layer.beginTime = timeSincePause;
}
CAPropertyAnimation
- 是CAAnimation的子類慌盯,也是個(gè)抽象類,要想創(chuàng)建動(dòng)畫對(duì)象掂器,應(yīng)該使用它的兩個(gè)子類:
- CABasicAnimation
- CAKeyframeAnimation
- 屬性說明:
- keyPath:通過指定CALayer的一個(gè)屬性名稱為keyPath(NSString類型)亚皂,并且對(duì)CALayer的這個(gè)屬性的值進(jìn)行修改,達(dá)到相應(yīng)的動(dòng)畫效果国瓮。比如灭必,指定@“position”為keyPath,就修改CALayer的position屬性的值乃摹,以達(dá)到平移的動(dòng)畫效果
CABasicAnimation——基本動(dòng)畫
- 基本動(dòng)畫禁漓,是CAPropertyAnimation的子類
- 屬性說明:
- fromValue:keyPath相應(yīng)屬性的初始值
- toValue:keyPath相應(yīng)屬性的結(jié)束值
- 動(dòng)畫過程說明:
- 隨著動(dòng)畫的進(jìn)行,在長度為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í)行前的初始值,并沒有真正被改變蹈集。
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對(duì)象减响。里面的元素稱為“關(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:可以為對(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í)間是平分的
- CABasicAnimation可看做是只有2個(gè)關(guān)鍵幀的CAKeyframeAnimation
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è)置動(dòng)畫對(duì)象的beginTime屬性來更改動(dòng)畫的開始時(shí)間
轉(zhuǎn)場動(dòng)畫——CATransition
- CATransition是CAAnimation的子類佛致,用于做轉(zhuǎn)場動(dòng)畫,能夠?yàn)閷犹峁┮瞥銎聊缓鸵迫肫聊坏膭?dòng)畫效果辙谜。iOS比Mac OS X的轉(zhuǎn)場動(dòng)畫效果少一點(diǎn)
- UINavigationController就是通過CATransition實(shí)現(xiàn)了將控制器的視圖推入屏幕的動(dòng)畫效果
- 動(dòng)畫屬性:
- type:動(dòng)畫過渡類型
- subtype:動(dòng)畫過渡方向
- startProgress:動(dòng)畫起點(diǎn)(在整體動(dòng)畫的百分比)
- endProgress:動(dòng)畫終點(diǎn)(在整體動(dòng)畫的百分比)
轉(zhuǎn)場動(dòng)畫過渡效果
使用UIView動(dòng)畫函數(shù)實(shí)現(xiàn)轉(zhuǎn)場動(dòng)畫——單視圖
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;
- 參數(shù)說明:
- duration:動(dòng)畫的持續(xù)時(shí)間
- view:需要進(jìn)行轉(zhuǎn)場動(dòng)畫的視圖
- options:轉(zhuǎn)場動(dòng)畫的類型
- animations:將改變視圖屬性的代碼放在這個(gè)block中
- completion:動(dòng)畫結(jié)束后俺榆,會(huì)自動(dòng)調(diào)用這個(gè)block
使用UIView動(dòng)畫函數(shù)實(shí)現(xiàn)轉(zhuǎn)場動(dòng)畫——雙視圖
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion;
- 參數(shù)說明:
- duration:動(dòng)畫的持續(xù)時(shí)間
- options:轉(zhuǎn)場動(dòng)畫的類型
- animations:將改變視圖屬性的代碼放在這個(gè)block中
- completion:動(dòng)畫結(jié)束后,會(huì)自動(dòng)調(diào)用這個(gè)block
CADisplayLink
- CADisplayLink是一種以屏幕刷新頻率觸發(fā)的時(shí)鐘機(jī)制装哆,每秒鐘執(zhí)行大約60次左右
- CADisplayLink是一個(gè)計(jì)時(shí)器罐脊,可以使繪圖代碼與視圖的刷新頻率保持同步,而NSTimer無法確保計(jì)時(shí)器實(shí)際被觸發(fā)的準(zhǔn)確時(shí)間
- 使用方法:
- 定義CADisplayLink并制定觸發(fā)調(diào)用方法
- 將顯示鏈接添加到主運(yùn)行循環(huán)隊(duì)列