iOS-核心動畫時序控制(譯)

這是我第一次翻譯國外大神的文章避诽。為了行文通順龟虎,某些地方?jīng)]有完全遵照原文。末尾附有自己的一些私貨沙庐。
原文鏈接如下:
http://ronnqvi.st/controlling-animation-timing/
如有疏漏鲤妥,敬請指出,不勝感激拱雏。

概述

在iOS的動畫框架中棉安,有一個叫做CAMediaTiming的協(xié)議,它由CAAnimation實現(xiàn)铸抑,而后者是CABasicAnimation和CAKeyframeAnimation的基類贡耽。所有和時序相關(guān)的屬性:duration, beginTime, repeatCount等等都是從這個協(xié)議中來的∪笛矗總體來說蒲赂,該協(xié)議定義了8個屬性,這8個屬性可以通過不同的組合方式來精確控制動畫時序刁憋。蘋果官方文檔對每個屬性的介紹都非常簡略滥嘴,因此閱讀官文會比閱讀這篇博客更快,但是我個人認為至耻,有關(guān)時序的問題若皱,最好還是結(jié)合圖表來理解。因此花費一些篇幅是有必要的有梆。

圖解CAMediaTiming

為了解釋和時序有關(guān)的各個屬性是尖,我現(xiàn)在要做一個顏色變化的動畫(橙->藍)。下圖中的格子表示一段動畫從開始到結(jié)束的整個時間線泥耀,而其中每一格代表時間線中的一秒饺汹。你可以看到整個動畫過程中任意時刻的顏色。

duration

下圖展示了設(shè)置duration=1.5時的情景痰催。

WX20170317-134617.png

CAAnimation會在動畫結(jié)束后默認從layer上移除兜辞,該過程同樣如圖上所示。一旦animation對象到達了它的“最終值”(animation的值通過“插值”法進行變化夸溶。關(guān)于“最終值”的解釋會附在文末逸吵。——譯者注)缝裁,它就會從layer上移除扫皱。如果layer原本的顏色是橙色(注意,不是說它的fromValue是orangeColor——譯者注),那么在動畫結(jié)束后layer將變回橙色韩脑。在該圖示中氢妈,layer的原本顏色是白色,所以在動畫添加到layer上1.5秒后段多,layer就會變成白色首量。

beginTime

如果我們再加上beginTime這個屬性會更好理解一些。如圖:

圖2.png

duration被設(shè)置為1.5秒进苍,beginTime被設(shè)置為currentTime(CACurrentMediaTime() + 1)加缘,所以動畫將在Animation對象被添加到layer上1秒后動畫開始執(zhí)行。2.5秒后結(jié)束觉啊。
如果要讓layer在動畫開始前顯示Animation的fromValue拣宏,你可以設(shè)置fillMode為kCAFillModeBackwards,來讓動畫“向后填充”杠人。圖示如下:

圖3.png

autoreverses

autoreverses屬性可以讓動畫從“起始值”執(zhí)行到“最終值”蚀浆,然后再反過來,從“終止值”執(zhí)行到“起始值”搜吧。因此,整個動畫執(zhí)行時間將會是duration 的2倍杨凑。

圖4.png

repeatCount

repeatCount可以將動畫重復(fù)執(zhí)行2次(如下圖所示)甚至任意次(你可以設(shè)置repeatCount為1.5滤奈,讓動畫執(zhí)行一次半)。一旦動畫執(zhí)行到了“最終值”它會立即回到“起始值”然后重新開始執(zhí)行撩满。請讀者將autoreverses和repeatCount屬性做一個對比蜒程。

圖5.png

repeatDuration

repeatDuration作用和repeatCount類似,但是卻很少用到伺帘。它會單純地在給定的時間內(nèi)(盡可能地)重復(fù)動畫昭躺。下圖所示為repeatCount=2時的情景。如果repeatDuration小于duration伪嫁,則動畫會提前結(jié)束(即動畫的真正執(zhí)行時間取決于repeatCount领炫。——譯者注)张咳。

圖6.png

以上屬性都可以組合使用帝洪。

圖7.png

speed

speed是一個更為有趣的時序?qū)傩浴H绻鹍uration=3脚猾,speed=2葱峡,則動畫執(zhí)行時間會是1.5秒。(即執(zhí)行時間=speed * duration)龙助。

圖8.png

如果只是為了控制一個簡單動畫的速度砰奕,你當(dāng)然可以通過設(shè)置beginTime和duration來達到目的。但是speed屬性的強大之處在于:

  • 動畫的速度具備“等級”關(guān)系。
  • CAAnimation不是唯一一個實現(xiàn)了CAMediaTiming的類军援。

速度的“等級關(guān)系”

如果一個動畫組(Animation Group)的speed為2仅淑,而其中一個動畫的speed為1.5,那么該動畫將會以三倍的速度播放盖溺。

CAMediaTiming的其他應(yīng)用

CAMediaTiming不僅被CAAnimation類實現(xiàn)漓糙,也同樣被CALayer實現(xiàn)。后者是所有核心動畫圖層的基類烘嘱。因此昆禽,對CALayer的speed賦值將會影響其上面添加的所有動畫。最終speed = layer.speed * animation.speed蝇庭。

動畫暫停

通過設(shè)置speed屬性為0醉鳖,我們可以暫停一個動畫。timeOffset屬性為我們提供了一個可以從外部控制動畫進程的機制哮内。例如盗棵,可以通過slider來查看動畫的每一個時刻的樣子。
timeOffset屬性乍一看會很奇怪北发。顧名思義纹因,該屬性用于抵消計算動畫狀態(tài)的時間。我們最好通過圖畫來解釋琳拨。下圖表示一個duration=3瞭恰,timeOffset=1的動畫。

圖9.png

該動畫直接調(diào)到“橙色->藍色”這個動畫過程的第1秒處開始執(zhí)行(此時它已經(jīng)不是純橙色了——譯者注)狱庇,直到2秒時完全變?yōu)樗{色惊畏。隨后,動畫跳轉(zhuǎn)到其純橙色然后執(zhí)行其第0秒第1秒的動畫過程密任。也就是說颜启,timeOffset將動畫01秒的過程抽取了出來,放到最后執(zhí)行浪讳。
這個屬性本身沒什么用處缰盏,但如果同時把speed設(shè)置為0,我們就可以控制動畫的“當(dāng)前狀態(tài)”驻债。被暫停的動畫將會卡在第一幀上乳规,如果你看上圖所示的帶偏移量的動畫最開始的顏色,你會發(fā)現(xiàn)它其實是顏色變化開始1秒后應(yīng)該呈現(xiàn)的顏色合呐。通過將timeOffset設(shè)置為其他值暮的,你可以看到動畫該時刻的樣子。

控制動畫時序

speed和timeOffset結(jié)合使用可以控制動畫的“當(dāng)前”時間淌实。如下所示是一個slider的實例冻辩,我們通過設(shè)置其timeOffset來查看方塊的顏色變化猖腕。

Slider

這個例子非常簡單,創(chuàng)建一個basic animation恨闪,加載到一個layer上倘感。我們把動畫的speed設(shè)置為0,讓它停下咙咽。

CABasicAnimation *changeColor =
   [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
changeColor.fromValue = (id)[UIColor orangeColor].CGColor;
changeColor.toValue   = (id)[UIColor blueColor].CGColor;
changeColor.duration  = 1.0; // For convenience

[self.myLayer addAnimation:changeColor
                   forKey:@"Change color"];
    
self.myLayer.speed = 0.0; // Pause the animation

然后在action方法中我們將slider的value賦值給做動畫的layer的timeOffset屬性:

- (IBAction)sliderChanged:(UISlider *)sender {
    self.myLayer.timeOffset = sender.value; // Update "current time"
}

效果圖:

動圖.gif

小結(jié)

  1. 通過設(shè)置fillMode為forward老玛,并將removedOnCompletion設(shè)為NO,可以讓圖層保持在動畫結(jié)束以后的狀態(tài)钧敞。但是注意蜡豹,animation對象只會影響到圖層的PresentationLayer,而對ModelLayer沒有影響溉苛。
  2. 如果對speed屬性賦負值镜廉,動畫會倒著執(zhí)行。

私貨

關(guān)于timeOffset

蘋果官方文檔的解釋:

Specifies an additional time offset in active local time.
翻譯過來就是“在本地活躍時間中指定一個額外的時間偏移量”愚战。

聽起來還是很費解是吧娇唯?其實timeOffset就是說,把動畫時序中開頭的某個時間段分割出來寂玲,“拼接”到動畫的末尾塔插。由于這個操作改變了動畫真正的起點,因此拓哟,動畫看起來就從分割處開始執(zhí)行了佑淀。

animation的插值法

對于動畫的“值”,蘋果給出了三個屬性彰檬,分別是fromValue, toValue, byValue。蘋果規(guī)定谎砾,最多可以同時給這三個屬性中的兩個賦值逢倍。運行時,動畫在“初始值”和“最終值”之間進行插值景图,從而確定各個時刻Layer的狀態(tài)较雕。初始值不一定是fromValue哦!
插值策略如下:

  • 賦值給fromValue和toValue:在fromValue挚币、toValue之間插值亮蒋。
  • 賦值給fromValue和byValue:在fromValue、fromValue + byValue之間插值妆毕。
  • 賦值給B和toValue:在toValue-byValue慎玖、toValue之間插值。
  • 賦值給fromValue:在fromValue和該屬性當(dāng)前的value之間插值笛粘。
  • 賦值給toValue:在keypath屬性的presentationlayer的當(dāng)前值和toValue之間插值趁怔。
  • 賦值給byValue:在keypath屬性的presentationlayer的當(dāng)前值和byValue之間插值湿硝。
  • 所有的都為nil:在keypath屬性的presentationlayer先前的值和現(xiàn)在的值之間插值。

對于最后一條润努,我自己也沒有嘗試成功過关斜。不知是不是個人理解出了偏差。這里先附上官文原文:

All properties are nil. Interpolates between the previous value of keyPath in the target layer’s presentation layer and the current value of keyPath in the target layer’s presentation layer.

歡迎各位大神指點铺浇!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末痢畜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鳍侣,更是在濱河造成了極大的恐慌丁稀,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拱她,死亡現(xiàn)場離奇詭異二驰,居然都是意外死亡,警方通過查閱死者的電腦和手機秉沼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門桶雀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人唬复,你說我怎么就攤上這事矗积。” “怎么了敞咧?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵棘捣,是天一觀的道長。 經(jīng)常有香客問我休建,道長乍恐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任测砂,我火速辦了婚禮茵烈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘砌些。我一直安慰自己呜投,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布存璃。 她就那樣靜靜地躺著仑荐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪纵东。 梳的紋絲不亂的頭發(fā)上粘招,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音偎球,去河邊找鬼男图。 笑死示姿,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逊笆。 我是一名探鬼主播栈戳,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼难裆!你這毒婦竟也來了子檀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤乃戈,失蹤者是張志新(化名)和其女友劉穎褂痰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體症虑,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡缩歪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谍憔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匪蝙。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖习贫,靈堂內(nèi)的尸體忽然破棺而出逛球,到底是詐尸還是另有隱情,我是刑警寧澤苫昌,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布颤绕,位于F島的核電站,受9級特大地震影響祟身,放射性物質(zhì)發(fā)生泄漏奥务。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一袜硫、第九天 我趴在偏房一處隱蔽的房頂上張望汗洒。 院中可真熱鬧,春花似錦父款、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肝集,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛛壳,已是汗流浹背所刀。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留浮创,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓砌函,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讹俊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

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

  • 在iOS中隨處都可以看到絢麗的動畫效果仍劈,實現(xiàn)這些動畫的過程并不復(fù)雜,今天將帶大家一窺ios動畫全貌贩疙。在這里你可以看...
    每天刷兩次牙閱讀 8,465評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果讹弯,實現(xiàn)這些動畫的過程并不復(fù)雜屋群,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,094評論 5 13
  • 先看看CAAnimation動畫的繼承結(jié)構(gòu) CAAnimation{ CAPropertyAnimation { ...
    時間不會倒著走閱讀 1,638評論 0 1
  • 1. 簡介 Core Animation 中文翻譯為核心動畫邪乍,它是一組非常強大的動畫處理API,使用它能做出非常炫...
    lltree閱讀 631評論 2 6
  • 介紹 : JLRoutes是一個調(diào)用極少代碼 , 可以很方便的處理不同URL schemes以及解析它們的參數(shù)对竣,并...
    CoderLF閱讀 1,627評論 0 3