內(nèi)容
關(guān)于圖層動(dòng)畫相關(guān)框架的介紹
CoreAnimation結(jié)構(gòu)及圖層動(dòng)畫
1. CoreGraphics,QuartzCore, CoreAnimation區(qū)別
對(duì)CoreGraphics肢执,QuartzCore, CoreAnimation 這三個(gè)概念傻傻分不清枉阵,先梳理一下
CoreGraphics(核心圖形)
iOS的核心圖形庫(kù),包含Quartz2D繪圖API接口,常用的是point预茄,size兴溜,rect等這些圖形,都定義在這個(gè)框架中耻陕,類名以CG開(kāi)頭的都屬于CoreGraphics框架拙徽,它提供的都是C語(yǔ)言函數(shù)接口,是可以在iOS和mac OS 通用的
QuartzCore
Quartz是位于Mac OS X的Drawin核心之上的繪圖層诗宣,這個(gè)框架感覺(jué)不是很清晰斋攀,但是看頭文件可以發(fā)現(xiàn),它就是CoreAnimation梧田,這個(gè)框架頭文件只包含了CoreAnimation.h
CoreAnimation(核心動(dòng)畫)
CoreAnimation翻譯過(guò)來(lái)就是核心動(dòng)畫,一組非常強(qiáng)大的API淳蔼,用來(lái)做動(dòng)畫的,非常的簡(jiǎn)單裁眯,但是效果非常絢麗
CoreAnimation是跨平臺(tái)的鹉梨,既可以支持IOS,也支持MAC OS
CoreAnimation執(zhí)行動(dòng)畫是在后臺(tái)穿稳,不會(huì)阻塞主線程
CoreAnimation作用在CALayer存皂,不是UIView
CoreGraphics和CoreAnimation的關(guān)系
首先它們都是跨iOS和Mac OS 使用的,這點(diǎn)區(qū)別于UIKit逢艘,并且CoreAnimation中大量使用到CoreGraphics中的類旦袋,因?yàn)閷?shí)現(xiàn)動(dòng)畫要用到圖形庫(kù)中的定西
為什么CA神馬神馬的,用的時(shí)候好多都要“.CGXXXX”呢它改?
layer.backgroundColor = [UIColor redColor].CGColor;
首先疤孕,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幸冻。
框架關(guān)系
image
可以看出,CoreGraphics是底層繪制框架辩越,我們實(shí)際會(huì)用到的也就是CG開(kāi)頭的一些底層繪制函數(shù)和變量,這是一個(gè)純C語(yǔ)言框架
QuartzCore(包含CoreAnimation)框架信粮,是iOS系統(tǒng)的基本渲染框架黔攒,是一個(gè)OC語(yǔ)言框架,是一套基于CoreGraphics的OC語(yǔ)言封裝强缘,封裝出了基本渲染類CALayer
2.CoreAnimation結(jié)構(gòu)及圖層動(dòng)畫 官方文檔
核心動(dòng)畫類結(jié)構(gòu)
image
CALayer 圖層類
CAAnimation 動(dòng)畫計(jì)時(shí)類
CAAnimationGroup 是個(gè)動(dòng)畫組督惰,可以同時(shí)進(jìn)行縮放,旋轉(zhuǎn)
CAPropertyAnimation 也是個(gè)抽象類旅掂,本身不具備動(dòng)畫效果赏胚,只有子類才有。
CATransition 轉(zhuǎn)場(chǎng)動(dòng)畫商虐,界面之間跳轉(zhuǎn)(切換)
CAConstraint 布局約束類
CATransaction 事物類觉阅,可以同時(shí)設(shè)置多個(gè)layer層的動(dòng)畫效果∶爻担可以通過(guò)隱式和顯式兩種方式來(lái)進(jìn)行動(dòng)畫操作
2.1 關(guān)于圖層
CALayer基本屬性
@property CGRect bounds; //寬度和高度
@property CGPoint position; //位置(默認(rèn)指中點(diǎn)典勇,具體由anchorPoint決定)
@property CGPoint anchorPoint; // 錨點(diǎn)(x,y的范圍都是0-1),決定了position的位置
@property CGColorRef backgroundColor; // 背景顏色(CGColorRef類型)
@property CATransform3D transform; //形變屬性
可動(dòng)畫屬性特點(diǎn):
* 直接對(duì)它付值可產(chǎn)生隱式動(dòng)畫
* CAAnimation的keyPath可以設(shè)置為這個(gè)屬性的名字
對(duì)這些屬性賦值的時(shí)候叮趴,layer會(huì)讓它的delegate調(diào)用actionForLayer:forKey:方法獲取一個(gè)返回值割笙,這個(gè)返回值可能是這樣幾種情況:
1、是一個(gè)nil眯亦,則layer會(huì)走自己的隱式動(dòng)畫伤溉;
2、是一個(gè)NSNull妻率,則layer不會(huì)做任何動(dòng)畫乱顾;
3、是一個(gè)實(shí)現(xiàn)了CAAction協(xié)議的對(duì)象宫静,則layer會(huì)用這個(gè)對(duì)象生成一個(gè)CABasicAnimation加到自己身上執(zhí)行動(dòng)畫
CALayer與UIView的關(guān)系
UIView之所以能顯示在屏幕上糯耍,完全是因?yàn)樗鼉?nèi)部的一個(gè)圖層:
在創(chuàng)建UIView對(duì)象時(shí)扔字,UIView內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)圖層(即CALayer對(duì)象),通過(guò)UIView的layer屬性可以訪問(wèn)這個(gè)層温技。
@property(nonatomic,readonly,retain) CALayer *layer;
當(dāng)UIView需要顯示到屏幕上時(shí)革为,會(huì)調(diào)用drawRect:方法進(jìn)行繪圖,并且會(huì)將所有內(nèi)容繪制在自己的圖層上舵鳞,繪圖完畢后震檩, 系統(tǒng)會(huì)將圖層拷貝到屏幕上,于是就完成了UIView的顯示蜓堕。
換句話說(shuō)抛虏,UIView本身不具備顯示的功能,是它內(nèi)部的層才有顯示功能套才。
對(duì)比CALayer迂猴,UIView多了一個(gè)事件處理的功能。也就是說(shuō)背伴,CALayer不能處理用戶的觸摸事件沸毁,而UIView可以
所以,如果顯示出來(lái)的東西需要跟用戶進(jìn)行交互的話傻寂,用UIView息尺;如果不需要跟用戶進(jìn)行交互,用UIView或者CALayer都可以疾掰。當(dāng)然搂誉,CALayer的性能會(huì)高一些,因?yàn)樗倭耸录幚淼墓δ芫裁剩虞p量級(jí)
總結(jié):CALayer作為一個(gè)跨平臺(tái)框架(OS X和iOS)QuatzCore的類炭懊,iOS系統(tǒng)
為了處理用戶交互事件(觸屏操作)用UIView封裝了一次CALayer,UIView本
身負(fù)責(zé)處理交互事件拂檩,其持有一個(gè)Layer凛虽,用來(lái)負(fù)責(zé)繪制這個(gè)View的內(nèi)容。而
我們對(duì)UIView的和繪制相關(guān)的屬性賦值和訪問(wèn)的時(shí)候(frame广恢、
backgroundColor等)UIView實(shí)際上是直接調(diào)用其Layer對(duì)應(yīng)的屬性(frame對(duì)
應(yīng)frame凯旋,center對(duì)應(yīng)position等)的getter和setter。
核心動(dòng)畫渲染框架
image
圖層樹(shù):包含每一層的對(duì)象模型值钉迷。他們就是你設(shè)定的圖層的屬性值
呈現(xiàn)樹(shù):包含了當(dāng)前動(dòng)畫發(fā)生時(shí)候?qū)⒁@示的值(例如你要給圖層背景顏色設(shè)置新的值的時(shí)候至非,它會(huì)立即修改圖層樹(shù)里面相應(yīng)的值。但是在呈現(xiàn)樹(shù)里面背景顏色值在將要顯示給用戶的時(shí)候才被更新為新值)
渲染樹(shù):在渲染圖層的時(shí)候使用呈現(xiàn)樹(shù)的值 (渲染樹(shù)負(fù)責(zé)執(zhí)行獨(dú)立于應(yīng)用活動(dòng)的復(fù)雜操作糠聪。渲染由一個(gè)單獨(dú)的進(jìn)程或線程來(lái)執(zhí)行荒椭,使其對(duì)應(yīng)用程序的運(yùn)行循環(huán)影響最小)
圖層幾何屬性(mac os 下坐標(biāo)系)
position:屬性是一個(gè)CGPoint值舰蟆, 指定圖層相當(dāng)于它父圖層的位置, 該值基于父圖層的坐標(biāo)系
bounds:屬性是CGRect值趣惠, 指定圖層的大小(bounds.size)和圖層的 原點(diǎn)(bounds.origin)
anchorPoint:屬性是CGPoint值狸棍,anchorPoint指定了bounds相對(duì)于position的值,同時(shí)作為變換的支點(diǎn)味悄,錨點(diǎn)使用單元空間坐標(biāo)系表示草戈,(0,0)接近圖層的原點(diǎn)侍瑟,(1唐片,1)原點(diǎn)的對(duì)角點(diǎn)。(當(dāng)你設(shè)置圖層的 frame 屬性的時(shí)候,position 會(huì)根據(jù)錨點(diǎn)(anchorPoint)相應(yīng)的改變,而當(dāng)你設(shè)置圖層的 position 屬性的候,bounds 會(huì)根據(jù)錨點(diǎn)(anchorPoint)做相應(yīng)的改變)
(錨點(diǎn)就是layer的那一個(gè)點(diǎn)在point上)
圖層的 frame涨颜、bounds费韭、position 和 anchorPoint 關(guān)系如下圖所示
anchorPoint 默認(rèn)值為(0.5,0.5),位于圖層的中心點(diǎn)。圖層的 position 值為(100.0,100.0),bounds 為(0.0,0.0,120,80.0)庭瑰。通過(guò)計(jì)算得到圖層的 frame為(40.0,60.0,120.0,80.0)
幾種常用的Layer
CAEmitterLayer
CAEmitterLayer是CoreAnimation框架中的粒子發(fā)射層星持,博客中有詳細(xì)的介紹和范例,這里不再重復(fù)弹灭,地址如下:粒子效果的應(yīng)用和火焰范例
CAGradientLayer
CAGradientLayer是用于色彩梯度展示的layer圖層督暂,通過(guò)CAGradientLayer,我們可以很輕松的創(chuàng)建出有過(guò)渡效果的色彩圖
CAReplicatorLayer
CAReplocatorLayer是拷貝視圖容器鲤屡,我們可以通過(guò)它损痰,將其中的子layer進(jìn)行拷貝福侈,并進(jìn)行一些差異處理
CAShapeLayer
CAShapeLayer是圖形layer層酒来,我們可以自定義這個(gè)層的形狀
CATextLayer
CATextLayer可以進(jìn)行文本的繪制
2.2 關(guān)于動(dòng)畫
UIViewAnimation動(dòng)畫
iOS開(kāi)發(fā)中,UIKit為我們封裝好的核心動(dòng)畫層的方法肪凛,通過(guò)這些方法堰汉,基本能達(dá)到我們項(xiàng)目的大多需求,其中UIView動(dòng)畫使用簡(jiǎn)便,開(kāi)發(fā)中應(yīng)用十分廣泛
UIView動(dòng)畫執(zhí)行的兩種方式
使用begin和commit方式
例如:
UIView * view = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
[self.view addSubview:view];
view.backgroundColor=[UIColor redColor];
[UIView beginAnimations:@"test" context:nil];
[UIView setAnimationDuration:3];
view.backgroundColor=[UIColor orangeColor];
[UIView commitAnimations];//執(zhí)行commit后伟墙,動(dòng)畫即開(kāi)始執(zhí)行
使用block塊api
例如:
[UIView animateWithDuration:1 animations:^{
_myView.alpha=0;
} completion:^(BOOL finished) {
if (finished) {
_myView.alpha=1;
}}];
支持動(dòng)畫的屬性
image
CAAnimation
如果你想更加自由的通過(guò)動(dòng)畫操作視圖的屬性翘鸭,你就需要跳過(guò)UIKit的封裝,使用CoreAnimation核心動(dòng)畫層的方法來(lái)實(shí)現(xiàn)動(dòng)畫,CoreAnimation能夠?qū)崿F(xiàn)更多復(fù)雜戳葵、好看就乓、高效的動(dòng)畫效果
* 陰影,圓角拱烁,帶顏色的邊框生蚁。
* 3D變化。
* 透明遮罩
* 多級(jí)非線性動(dòng)畫
CAAnimation是CoreAnimation框架中執(zhí)行動(dòng)畫的基類戏自,是個(gè)抽象類邦投,不具備動(dòng)畫效果,必須用它的子類才有動(dòng)畫效果,是所有動(dòng)畫對(duì)象的父類擅笔,負(fù)責(zé)控制動(dòng)畫的持續(xù)時(shí)間和速度
隱式動(dòng)畫:不指定任何動(dòng)畫類型志衣,僅改變非根層layer(手動(dòng)創(chuàng)建的layer)動(dòng)畫屬性屯援,coreAnimation會(huì)決定如何何時(shí)去做動(dòng)畫,你不用做額外操作
顯式動(dòng)畫:需要?jiǎng)?chuàng)建一個(gè)動(dòng)畫對(duì)象念脯,并設(shè)置開(kāi)始和結(jié)束值狞洋,直到把動(dòng)畫應(yīng)用到某圖層上,動(dòng)畫才開(kāi)始執(zhí)行
CAAnimation相關(guān)的幾個(gè)動(dòng)畫類的關(guān)系圖
image
CAPropertyAnimation
是CAAnimation的子類和二,也是個(gè)抽象類徘铝,要想創(chuàng)建動(dòng)畫對(duì)象,應(yīng)該使用它的兩個(gè)子類:CABasicAnimation和CAKeyframeAnimation
@property(nullable, copy) NSString *keyPath;
通過(guò)指定CALayer的一個(gè)屬性名稱為keyPath(NSString類型)惯吕,并且對(duì)CALayer的這個(gè)屬性的值進(jìn)行修改惕它,達(dá)到相應(yīng)的動(dòng)畫效果
CABasicAnimation
基本動(dòng)畫,通過(guò)設(shè)定起始點(diǎn)废登,終點(diǎn)淹魄,時(shí)間,動(dòng)畫會(huì)沿著你這設(shè)定點(diǎn)進(jìn)行移動(dòng)堡距,
隨著動(dòng)畫的進(jìn)行甲锡,在長(zhǎng)度為duration的持續(xù)時(shí)間內(nèi),keyPath相應(yīng)屬性的值從fromValue漸漸地變?yōu)閠oValue羽戒。
CAKeyframeAnimation
主要操作屬性有keyPath和values值組合缤沦,以通過(guò)設(shè)定CALayer的始點(diǎn)、中間關(guān)鍵點(diǎn)易稠、終點(diǎn)的frame缸废,時(shí)間,動(dòng)畫會(huì)沿你設(shè)定的軌跡進(jìn)行移動(dòng)
與CABasicAnimation的區(qū)別是:
CABasicAnimation只能從一個(gè)數(shù)值(fromValue)變到另一個(gè)數(shù)值(toValue)驶社,而CAKeyframeAnimation會(huì)使用一個(gè)NSArray保存這些數(shù)值
CABasicAnimation可看做是只有2個(gè)關(guān)鍵幀的CAKeyframeAnimation
CAAnimationGroup
可以保存一組動(dòng)畫對(duì)象企量,將CAAnimationGroup對(duì)象加入層后,組中所有動(dòng)畫對(duì)象可以同時(shí)并發(fā)運(yùn)行
CATransition
用于做轉(zhuǎn)場(chǎng)動(dòng)畫亡电,能夠?yàn)閷犹峁┮瞥銎聊缓鸵迫肫聊坏膭?dòng)畫效果届巩。iOS比Mac OS X的轉(zhuǎn)場(chǎng)動(dòng)畫效果少一點(diǎn)。
UINavigationController就是通過(guò)CATransition實(shí)現(xiàn)了將控制器的視圖推入屏幕的動(dòng)畫效果份乒。
使用CoreAnimation做動(dòng)畫的時(shí)候恕汇,遵循四步就好
1.創(chuàng)建CAAnmation子對(duì)象
2.設(shè)置CAAnmation的屬性
3.調(diào)用CALayer的addAnimation:forKey將CAAnimation對(duì)象添加到CALayer上,就能執(zhí)行動(dòng)畫
4.調(diào)用CALayer的removeAnimationForKey方法可以停止CALayer中的動(dòng)畫
遺留問(wèn)題
隱式動(dòng)畫或辖,顯式動(dòng)畫和隱式事務(wù)瘾英,顯示事務(wù)混淆
沒(méi)有用到CATransaction begin,commit 依然有動(dòng)畫效果
概念補(bǔ)充
顯式動(dòng)畫&隱式動(dòng)畫
CALayer的動(dòng)畫分為隱式動(dòng)畫和顯式動(dòng)畫,UIView內(nèi)部關(guān)聯(lián)了一個(gè)CALayer孝凌,叫它“Root CALayer”.
所有的非Root CALayer的“Animatable”屬性在修改的時(shí)候會(huì)默認(rèn)的產(chǎn)生隱式動(dòng)畫
CATransaction 事務(wù)
CATransaction 是核心動(dòng)畫里負(fù)責(zé)協(xié)調(diào)多個(gè)動(dòng)畫更新顯示操作方咆,保證多個(gè)動(dòng)畫同時(shí)進(jìn)行,用于配置隱式動(dòng)畫蟀架,即CALayer屬性修改依賴CATransaction.
和動(dòng)畫類似CATransaction也分為隱式事務(wù)和顯式事務(wù)
隱式事務(wù):在某次RunLoop中設(shè)置了一個(gè)“Animatable”屬性瓣赂,如果當(dāng)前沒(méi)有設(shè)置事務(wù)榆骚,則會(huì)自動(dòng)創(chuàng)建一個(gè)CATransaction,并在當(dāng)前線程的下一個(gè)RunLoop中commit這個(gè)CATransaction
顯式事務(wù):直接調(diào)用CATransaction的[CATransaction begin]煌集,[CATransaction commit]等相關(guān)方法
另外事務(wù)可以嵌套妓肢,當(dāng)事務(wù)嵌套時(shí)候,只有最外層的事務(wù)commit了之后苫纤,整個(gè)動(dòng)畫才會(huì)執(zhí)行碉钠。