Core Animation

這篇我們來討論下Core Animation的原理和在iOS開發(fā)中的應(yīng)用.

Core Animation原理

Core Animation是用來展示view或者其他可見元素動(dòng)畫的機(jī)制顿膨。有了Core Animation(以下簡(jiǎn)稱CA), 開發(fā)人員只需要配置一些簡(jiǎn)單的動(dòng)畫參數(shù)就能夠創(chuàng)建出流暢的原生動(dòng)畫仗考,例如開始位置,結(jié)束位置(basic core animation類)等等. 在Apple的框架中,Core Animation所處位置如下圖所示:

CA結(jié)構(gòu)

可以看到继控,CA位于UIKit和AppKit下方,算是一個(gè)較為底層的框架。CA存在于QuartzCore framework,這里面也包含一些OpenGL和Graphics的子框架贯被。這些框架會(huì)將生成的動(dòng)畫、圖片等圖像信息傳給底層的繪圖硬件(caching成bitmap),產(chǎn)生最終用戶看到的界面彤灶。

CA涉及兩個(gè)部分看幼,一是CALayer, 另一個(gè)是Animation. 我們先來講CALayer。

CALayer

在iOS中枢希,UIView是我們我們最常用的一個(gè)類桌吃,整個(gè)的UIView是建立在CA層上的,每個(gè)UIView及其子類都存在一個(gè)layer層(root layer)苞轿。這個(gè)層是干什么的呢?
相信你們或多或少都寫過這樣的代碼吧:

 demoLabel.layer.cornerRadius = 5.f;
 demoLabel.layer.borderColor = []UIColor grayColor];
 demoLabel.layer.borderWidth = 1.f;

代碼中的layer就是CALayer逗物。 CALayer是用來管理布局屬性的搬卒,即用戶可見部分,也就是說翎卓,我們看到的一個(gè)個(gè)label, textView契邀,button都是CALayer幫助我們畫出的,而UIView失暴,UITextView以及UIButton都是CALayer的一個(gè)封裝坯门,為其提供了事件響應(yīng)能力。當(dāng)然逗扒,平常我們寫代碼時(shí)古戴,一些簡(jiǎn)單的可見屬性例如background color是可以用UIView本身來設(shè)置的,但是一旦涉及到復(fù)雜精細(xì)的界面效果, 則非CALayer莫屬矩肩。

在本篇中现恼,我們不講述CALayer是如何在iOS和OSX中的布局方式和不同的坐標(biāo)系統(tǒng),若您想了解的話黍檩,可點(diǎn)擊以下兩個(gè)鏈接: 有<a href="http://www.reibang.com/p/c6714dda9a9c">中文版</a>和<a >英文版</a>可供選擇叉袍,英文是Apple Doc里的,官方內(nèi)容; 中文版來自簡(jiǎn)書刽酱。在本篇中喳逛,我們偏向更理論的部分。

和UIView一樣棵里,layer也有樹形結(jié)構(gòu)润文,也有sublayer, superlayer之分衍慎。我們可以參考下圖:

Layer層級(jí)

如圖所示转唉,我們可以像添加subview一樣添加sublayer,最終產(chǎn)生的效果是一樣的稳捆。 而且右側(cè)的layer樹也和UIView的層級(jí)樹一樣自頂向下赠法。本質(zhì)上說,UIView的層級(jí)樹都會(huì)轉(zhuǎn)換成layer的樹形結(jié)構(gòu), 交給底層的繪圖硬件去處理,性能也因此得到了極大的提升砖织。

CALayer,或者說我們經(jīng)常說的layer款侵,本質(zhì)上是一個(gè)model tree,它是系統(tǒng)用來存儲(chǔ)當(dāng)前屬性的object侧纯,例如一些動(dòng)畫的target value新锈, 起始值,結(jié)束值等等眶熬。但是妹笆,在CA中的CALayer可不止一個(gè)model tree,還有2個(gè)娜氏,分別是presentation tree和render tree拳缠。它們3個(gè)分別反映了動(dòng)畫狀態(tài)的不同方面。我們之前已經(jīng)說過model tree用來存儲(chǔ)一些靜態(tài)屬性贸弥,平常我們的賦值操作就是直接和model tree進(jìn)行交互窟坐。與此同時(shí),presentation和render tree中也生成了和model tree相同的對(duì)應(yīng)樹形結(jié)構(gòu),為將來動(dòng)畫展示做準(zhǔn)備绵疲。不同的是哲鸳,render tree是私有的object, 對(duì)我們不可見,被用來渲染動(dòng)畫(數(shù)據(jù)), 其運(yùn)行的線程在比當(dāng)前app主線程優(yōu)先級(jí)還高盔憨,是在Apple的render server進(jìn)程中進(jìn)行的渲染徙菠,不會(huì)造成主線程堵塞。細(xì)心地你當(dāng)然也會(huì)發(fā)現(xiàn)這樣會(huì)增加進(jìn)程間通訊的開銷般渡,所以Apple不建議開發(fā)者手動(dòng)commit transaction而是默認(rèn)在run loop中提交事務(wù)(進(jìn)程間傳遞的數(shù)據(jù)主要有整個(gè)render tree和對(duì)應(yīng)的動(dòng)畫)懒豹。 三種tree關(guān)系如下圖所示:

3中l(wèi)ayer對(duì)比

CALayer中還有個(gè)比較重要的概念就是它具有層級(jí)關(guān)系的時(shí)間系統(tǒng), CALayer實(shí)現(xiàn)了CAMediaTiming協(xié)議,用來控制動(dòng)畫的展示等驯用,例如暫停和恢復(fù)脸秽。這部分內(nèi)容我們另起一篇講.

Animation

眾所周知,Apple的對(duì)動(dòng)畫的處理真是流暢之極蝴乔,細(xì)膩的也恰到好處记餐。比方說,對(duì)于root layer來說薇正,添加動(dòng)畫一般會(huì)調(diào)用UIViewAnimationWithBlocks這個(gè)category中的animateWithDuration系列方法, 使用者只需要在callback中寫入想執(zhí)行動(dòng)畫的代碼即可.類似spring這樣的具有damping效果的動(dòng)畫也可以這樣添加片酝。

但是,這些都是較為簡(jiǎn)單的動(dòng)畫挖腰,而且針對(duì)的是root layer雕沿。那如果我們的layer是我們自己添加的sublayer該怎么辦呢?答案也很簡(jiǎn)單猴仑,添加顯式動(dòng)畫审轮。之前提供的那個(gè)<a >中文版</a>鏈接中有不同layer添加動(dòng)畫的demo code, 包括設(shè)置各種不同屬性等等,大家可以參考。我在這里更多的是探討下Animation的結(jié)構(gòu).

Animation結(jié)構(gòu)

顯式動(dòng)畫的基類為CAAnimation,常用的是CABasicAnimation, CAKeyframeAnimation有時(shí)候還會(huì)使用到CAAnimationGroup來做組合動(dòng)畫. 不過我們這次只講比較重要的CABasicAnimation和CAKeyframeAnimation疾渣,其他的有機(jī)會(huì)再講篡诽。

不管是CABasicAnimation還是CAKeyframeAnimation都是繼承于CAPropertyAnimation.


Basic Animation

圖中有3個(gè)屬性, fromValue, toValue和interpolated point.這三個(gè)都是可選的, 但是不得同時(shí)多于2個(gè)為非空,一般來說榴捡,我們僅指定起始點(diǎn)和終點(diǎn)即可杈女,中間的值由timing function插值計(jì)算出來, 默認(rèn)是線性變換. Timing function是控制插值計(jì)算的,形象點(diǎn)說是Timing Function決定了動(dòng)畫運(yùn)行的節(jié)奏(Pacing), 比如是均勻變化(相同時(shí)間變化量相同),先快后慢,先慢后快還是先慢再快再慢. 例如我們?cè)诮oview添加動(dòng)畫時(shí)吊圾,會(huì)指定一些option例如 curveIn, curverOut, flip等等达椰,這些其實(shí)實(shí)現(xiàn)時(shí)都是依靠時(shí)間函數(shù)來實(shí)現(xiàn)。時(shí)間函數(shù)本質(zhì)是映射项乒,決定了時(shí)間和對(duì)應(yīng)的變化量砰碴,例如一秒內(nèi)透明度的變化. 當(dāng)使用basicAnimation時(shí), 自定義的timing function可以是一條光滑的貝塞爾曲線, 由起點(diǎn),終點(diǎn)和2個(gè)關(guān)鍵點(diǎn)控制: 如下圖:

貝塞爾曲線

但是如果動(dòng)畫比較復(fù)雜, 既不是直線板丽,也不是貝塞爾曲線, 那么就需要通過CAKeyframeAnimation來實(shí)現(xiàn). 關(guān)鍵幀動(dòng)畫很強(qiáng)大,可以讓我們充分的實(shí)現(xiàn)我們自定義的動(dòng)畫效果趁尼,例如落葉的飄落埃碱,縱向翻轉(zhuǎn)(轉(zhuǎn)場(chǎng)動(dòng)畫)等等。當(dāng)然你可以用嵌套basicAnimation的方式實(shí)現(xiàn)(平移+旋轉(zhuǎn))酥泞,但是那樣既復(fù)雜砚殿,代碼不簡(jiǎn)潔,而且動(dòng)畫很生硬芝囤。但Apple給了我們解決方案---keyFrame Animation!

 + (void)animateKeyframesWithDuration:(NSTimeInterval)duration 
                                delay:(NSTimeInterval)delay 
                              options:(UIViewKeyframeAnimationOptions)options 
                           animations:(void (^)(void))animations 
                           completion:(void (^__nullable)(BOOL finished))completion

+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime 
                        relativeDuration:(double)frameDuration 
                              animations:(void (^)(void))animations
  1. frameStartTime 表示關(guān)鍵幀動(dòng)畫開始的時(shí)刻在整個(gè)動(dòng)畫中的百分比
  2. frameDuration 表示這個(gè)關(guān)鍵幀動(dòng)畫占用整個(gè)動(dòng)畫時(shí)長的百分比

我們需要做的就是在第一個(gè)方法中添加關(guān)鍵幀, 設(shè)定開始時(shí)間和持續(xù)時(shí)間, 并在animation callback中設(shè)置某個(gè)keyFrame結(jié)束時(shí)的view位置似炎,透明度等等, 之后,系統(tǒng)會(huì)為我們插入中間幀, 確保動(dòng)畫的平滑悯姊。在關(guān)鍵幀動(dòng)畫中還有一個(gè)非常重要的參數(shù),那便是calculationMode,計(jì)算模式. 他決定插值的方式: 即當(dāng)在平面座標(biāo)系中有多個(gè)離散的點(diǎn)的時(shí)候,可以是離散的,也可以直線相連后進(jìn)行插值計(jì)算,也可以使用圓滑的曲線將他們相連后進(jìn)行插值計(jì)算:

  1. UIViewKeyframeAnimationOptionCalculationModeLinear // 連續(xù)運(yùn)算模式羡藐,線性
  2. UIViewKeyframeAnimationOptionCalculationModeDiscrete // 離散運(yùn)算模式,只顯示關(guān)鍵幀
  3. UIViewKeyframeAnimationOptionCalculationModePaced // 均勻執(zhí)行運(yùn)算模式悯许,線性
  4. UIViewKeyframeAnimationOptionCalculationModeCubic // 平滑運(yùn)算模式
  5. UIViewKeyframeAnimationOptionCalculationModeCubicPaced // 平滑均勻運(yùn)算模式

總結(jié)

Apple的CoreAnimation由兩部分組成: CALayer和Animation. 它們兩個(gè)分別確保了view的顯示和動(dòng)畫的平滑仆嗦。深刻理解core animation的原理不僅有助于我們調(diào)試代碼, 理解他們之間的關(guān)系,更可以幫助我們創(chuàng)造出優(yōu)美且性能優(yōu)越的動(dòng)畫, 提升用戶體驗(yàn).

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末先壕,一起剝皮案震驚了整個(gè)濱河市瘩扼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垃僚,老刑警劉巖集绰,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異谆棺,居然都是意外死亡栽燕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纫谅,“玉大人炫贤,你說我怎么就攤上這事「讹酰” “怎么了兰珍?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長询吴。 經(jīng)常有香客問我掠河,道長,這世上最難降的妖魔是什么猛计? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任唠摹,我火速辦了婚禮,結(jié)果婚禮上奉瘤,老公的妹妹穿的比我還像新娘勾拉。我一直安慰自己,他們只是感情好盗温,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布藕赞。 她就那樣靜靜地躺著,像睡著了一般卖局。 火紅的嫁衣襯著肌膚如雪斧蜕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天砚偶,我揣著相機(jī)與錄音批销,去河邊找鬼。 笑死染坯,一個(gè)胖子當(dāng)著我的面吹牛均芽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播酒请,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼骡技,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了羞反?” 一聲冷哼從身側(cè)響起布朦,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昼窗,沒想到半個(gè)月后是趴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡澄惊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年唆途,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了富雅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肛搬,死狀恐怖没佑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情温赔,我是刑警寧澤蛤奢,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站陶贼,受9級(jí)特大地震影響啤贩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拜秧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一痹屹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧枉氮,春花似錦志衍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至佃牛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間医舆,已是汗流浹背俘侠。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔬将,地道東北人爷速。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像霞怀,于是被迫代替她去往敵國和親惫东。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

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

  • 書寫的很好毙石,翻譯的也棒廉沮!感謝譯者,感謝感謝徐矩! iOS-Core-Animation-Advanced-Techni...
    錢噓噓閱讀 2,303評(píng)論 0 6
  • 個(gè)人博客地址:Lixuzong's Blog 我們所在屏幕上看到的都是Core Animation框架提供的滞时,所以...
    猿鹿說閱讀 455評(píng)論 0 1
  • 核心動(dòng)畫(Core Animation)一、Core animation簡(jiǎn)單介紹 1.Core Animatio...
    北辰青閱讀 1,046評(píng)論 0 1
  • 我們寫的應(yīng)用程序往往都不是靜態(tài)的滤灯,因?yàn)樗鼈冃枰m應(yīng)用戶的需求以及為執(zhí)行各種任務(wù)而改變狀態(tài)坪稽。 在這些狀態(tài)之間轉(zhuǎn)換時(shí)曼玩,...
    sunmumu1222閱讀 712評(píng)論 0 2
  • 2014年,我去了敦煌窒百,一個(gè)人去的黍判,沒有和林歡,那個(gè)時(shí)候我們已經(jīng)分手三年了篙梢。 其實(shí)我沒有資格說分手這兩個(gè)字顷帖,我從來...
    熊貓微刊閱讀 215評(píng)論 0 5