最近在閱讀《IOS核心動畫高級技巧》這本書驹暑,里面說到了完全自定義緩沖函數(shù)的方法。里面講解并不是很詳細京办,我在這里說一下自己的見解帆焕。具體情節(jié),大家可以閱讀這本書,這篇文章可以參考那本書的10.8的Demo换吧。
在Core? Animation中钥星,動畫是作用在CALayer上的。為了能更加模擬使動畫更加能模擬現(xiàn)實生活暴拄,比如說编饺,汽車在路上,汽車是經(jīng)過加速透且,勻速,然后減速到達終點的鲸沮,所以動畫也應該具有這樣類似的屬性锅论,有時候動畫還必須具備彈簧的感覺,即汽車還有時候會駛過終點最易,然后再回來終點。為了實現(xiàn)這種效果剔猿,Core? Animation定義了CAMediaTimingFunction這個屬性嬉荆,稱之為緩沖函數(shù),而且Core Animation還提供一系列的標準函數(shù)給我們使用汪茧,這些標準函數(shù)有:
kCAMediaTimingFunctionLinear
kCAMediaTimingFunctionEaseIn
kCAMediaTimingFunctionEaseOut
kCAMediaTimingFunctionEaseInEaseOut
kCAMediaTimingFunctionDefault
在這里蝶锋,將說明自定義緩沖函數(shù)的原理,并不會對這些標準緩沖函數(shù)加以說明扳缕。這些標準函數(shù)也沒有實現(xiàn)彈簧的感覺,即不能越過終點驴剔。
在完全自定義緩沖函數(shù)中粥庄,我們將放棄CAMediaTimingFunction屬性。利用CAKeyframeAnimation可以自己做一個類似緩沖函數(shù)的動畫來布讹。
首先我們必須明白训堆,動畫其實是不斷變化的數(shù)據(jù),所以我們控制這些數(shù)據(jù)的變化坑鱼,讓數(shù)據(jù)按我們指定的速率和加速度來增長或者減少,我們就實現(xiàn)了緩沖動畫呼股。在這里引申出兩個概念:動畫時間數(shù)據(jù)和動畫數(shù)據(jù)画恰。動畫時間數(shù)據(jù)是動畫運行需要一個時間段,時間段里面每個時間點就是動畫時間數(shù)據(jù)允扇。動畫數(shù)據(jù)是要改變的CALayer的屬性值在每個動畫時間里應該擁有的數(shù)值蔼两。說白了,動畫數(shù)據(jù)y跟動畫時間數(shù)據(jù)x形成的函數(shù)關系就是緩沖函數(shù)了额划。如果我們清楚了解到我們所需要的動畫數(shù)據(jù)跟動畫時間數(shù)據(jù)的關系,我們就可以利用動畫時間求出動畫數(shù)據(jù)揖赴,然后我們將動畫數(shù)據(jù)存儲在CAKeyframeAnimation的values數(shù)組里抑胎,我們便可以實現(xiàn)緩沖動畫了。
在這里阿逃,我將講解《IOS核心動畫高級技巧》10.8的Demo赃蛛。
上圖方法中呕臂,我們先用變量存儲我們動畫數(shù)據(jù)的開始點(fromValue)和結束點(toValue)肪跋。然后存儲動畫運行的總時間。在for循環(huán)里面谜洽,我們利用動畫數(shù)據(jù)和動畫時間數(shù)據(jù)的函數(shù)關系求出所有的動畫數(shù)據(jù)吴叶,并且存儲在frams數(shù)組中,最后傳遞給CAKeyframeAnimation的values數(shù)組里面∥钪#現(xiàn)在我們就要看看bounceEseOut()函數(shù)和-interpolateFromValue:toValue:time:方法是怎么回事?首先來看一下-interpolateFromValue:toValue:time:方法:
-interpolateFromValue:toValue:time:方法會返回一個NSValue對象磕洪,這就是我說的動畫數(shù)據(jù)了诫龙。-interpolateFromValue:toValue:time:方法使用了interpolate函數(shù)签赃。interpolate函數(shù)是求出動畫數(shù)據(jù)的關鍵,interpolate函數(shù)很簡單锦聊,根據(jù)time,fromValue和toValue求出動畫數(shù)據(jù)尺上,這個fromValue和toValue是一直不變的圆到,關鍵點就在于這個time,這個time也不是我說的動畫時間數(shù)據(jù)芽淡。至此我應該說明一下哪個是動畫時間數(shù)據(jù)x了:
float time =1/(float) numFrames * i;
我們可以想象,動畫總的運行時間是一個時間段富稻,里面每個時間點就是我們所要動畫時間數(shù)據(jù)了,而上面提供了60個這樣的時間點耙饰,這些時間點就是動畫時間數(shù)據(jù)了纹份,從上可以看出動畫時間數(shù)據(jù)的范圍是0到1。而在interpolate函數(shù)中的time只是包含了緩沖函數(shù)關系的數(shù)據(jù)(這些數(shù)據(jù)的范圍是0到1)蔓涧,根據(jù)fromValue和toValue放大一下緩沖函數(shù)關系的數(shù)據(jù)就是動畫數(shù)據(jù)了。
interpolate函數(shù)中的time來源于bounceEseOut()函數(shù)笋额,而這個bounceEseOut()函數(shù)就是我們所需要定義的緩沖函數(shù)啦。我們可以簡單看出茉盏,緩沖函數(shù)有4個段枢冤。根據(jù)書中10.8的Demo的動畫現(xiàn)象,第一段是彈球掉到終點動畫淹真,第二三段是彈球在反彈的動畫,第四段是彈球彈完后掉到終點的動畫核蘸。