iOS 動(dòng)畫

轉(zhuǎn)自:iOS動(dòng)畫詳解
原博主寫的特別棒,在此收藏一遍以防丟失,供自己學(xué)習(xí)參考之用。
另,原文為Swift版本,本篇轉(zhuǎn)為Objective-C版本。

一、基礎(chǔ)知識(shí)

CAAnimation.png

二、CABasicAnimation

1. 動(dòng)畫的屬性和解釋

屬性 解釋
duration 動(dòng)畫的持續(xù)時(shí)間
repeatCount 動(dòng)畫持續(xù)次數(shù)
repeatDuration 設(shè)置動(dòng)畫的時(shí)間,在該時(shí)間內(nèi)動(dòng)畫一直執(zhí)行,不計(jì)次數(shù)
beginTime 指定動(dòng)畫開(kāi)始的時(shí)間。從開(kāi)始延遲幾秒的話,設(shè)置為CACurrentMediaTime() + 秒數(shù) 的方式
timingFunction 設(shè)置動(dòng)畫的速度變化
fillMode 動(dòng)畫在開(kāi)始和結(jié)束時(shí)的動(dòng)作,默認(rèn)值是 kCAFillModeRemoved
autoreverses 動(dòng)畫結(jié)束時(shí)是否執(zhí)行逆動(dòng)畫
fromValue 所改變屬性的起始值
toValue 所改變屬性的結(jié)束時(shí)的值
byValue 所改變屬性相同起始值的改變量
keyPath 可以指定keyPath為CALayer的屬性值,并對(duì)它的值進(jìn)行修改,以達(dá)到對(duì)應(yīng)的動(dòng)畫效果,需要注意的是部分屬性值是不支持動(dòng)畫效果的

以下是具有動(dòng)畫效果的keyPath:

     //CATransform3D Key Paths : (example)transform.rotation.z
     //rotation.x
     //rotation.y
     //rotation.z
     //rotation 旋轉(zhuǎn)
     //scale.x
     //scale.y
     //scale.z
     //scale 縮放
     //translation.x
     //translation.y
     //translation.z
     //translation 平移

     //CGPoint Key Paths : (example)position.x
     //x
     //y

     //CGRect Key Paths : (example)bounds.size.width
     //origin.x
     //origin.y
     //origin
     //size.width
     //size.height
     //size

     //opacity
     //backgroundColor
     //cornerRadius 
     //borderWidth
     //contents 

     //Shadow Key Path:
     //shadowColor 
     //shadowOffset 
     //shadowOpacity 
     //shadowRadius

2.屬性值的解釋

  • repeatCount:(一直重復(fù)的情況)
    SwiftFloat.infinity
    OCHUGE_VALF

  • TimingFunction:

    timingFunction.png

kCAMediaTimingFunctionLinear
,在整個(gè)動(dòng)畫時(shí)間內(nèi)動(dòng)畫都是以一個(gè)相同的速度來(lái)改變。也就是勻速運(yùn)動(dòng)。一個(gè)線性的計(jì)時(shí)函數(shù),同樣也是CAAnimation的timingFunction屬性為空時(shí)候的默認(rèn)函數(shù)。線性步調(diào)對(duì)于那些立即加速并且保持勻速到達(dá)終點(diǎn)的場(chǎng)景會(huì)有意義(例如射出槍膛的子彈)。
kCAMediaTimingFunctionEaseIn
動(dòng)畫開(kāi)始時(shí)會(huì)較慢,之后動(dòng)畫會(huì)加速。一個(gè)慢慢加速然后突然停止的方法。對(duì)于之前提到的自由落體的例子來(lái)說(shuō)很適合,或者比如對(duì)準(zhǔn)一個(gè)目標(biāo)的導(dǎo)彈的發(fā)射。
kCAMediaTimingFunctionEaseOut
動(dòng)畫在開(kāi)始時(shí)會(huì)較快,之后動(dòng)畫速度減慢。它以一個(gè)全速開(kāi)始,然后慢慢減速停止。它有一個(gè)削弱的效果,應(yīng)用的場(chǎng)景比如一扇門慢慢地關(guān)上,而不是砰地一聲。
kCAMediaTimingFunctionEaseInEaseOut
動(dòng)畫在開(kāi)始和結(jié)束時(shí)速度較慢,中間時(shí)間段內(nèi)速度較快。創(chuàng)建了一個(gè)慢慢加速然后再慢慢減速的過(guò)程。這是現(xiàn)實(shí)世界大多數(shù)物體移動(dòng)的方式,也是大多數(shù)動(dòng)畫來(lái)說(shuō)最好的選擇。如果只可以用一種緩沖函數(shù)的話,那就必須是它了。那么你會(huì)疑惑為什么這不是默認(rèn)的選擇,實(shí)際上當(dāng)使用UIView的動(dòng)畫方法時(shí),他的確是默認(rèn)的,但當(dāng)創(chuàng)建CAAnimation的時(shí)候,就需要手動(dòng)設(shè)置它了。
kCAMediaTimingFunctionDefault
它和kCAMediaTimingFunctionEaseInEaseOut很類似,但是加速和減速的過(guò)程都稍微有些慢。它和kCAMediaTimingFunctionEaseInEaseOut的區(qū)別很難察覺(jué),可能是蘋果覺(jué)得它對(duì)于隱式動(dòng)畫來(lái)說(shuō)更適合(然后對(duì)UIKit就改變了想法,而是使用kCAMediaTimingFunctionEaseInEaseOut作為默認(rèn)效果),雖然它的名字說(shuō)是默認(rèn)的,但還是要記住當(dāng)創(chuàng)建顯式的CAAnimation它并不是默認(rèn)選項(xiàng)(換句話說(shuō),默認(rèn)的圖層行為動(dòng)畫用kCAMediaTimingFunctionDefault作為它們的計(jì)時(shí)方法)。
使用方法:

moveAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  • FillMode
    fillMode.png

kCAFillModeForwards :
動(dòng)畫開(kāi)始之后layer的狀態(tài)將保持在動(dòng)畫的最后一幀,而removedOnCompletion的默認(rèn)屬性值是YES,所以為了使動(dòng)畫結(jié)束之后layer保持結(jié)束狀態(tài),應(yīng)將removedOnCompletion設(shè)置為NO。
kCAFillModeBackwards :
將會(huì)立即執(zhí)行動(dòng)畫的第一幀,不論是否設(shè)置了 beginTime屬性。觀察發(fā)現(xiàn),設(shè)置該值,剛開(kāi)始視圖不見(jiàn),還不知道應(yīng)用在哪里。
kCAFillModeBoth:
該值是 kCAFillModeForwardskCAFillModeBackwards的組合狀態(tài)
kCAFillModeRemoved:
動(dòng)畫將在設(shè)置的 beginTime 開(kāi)始執(zhí)行(如沒(méi)有設(shè)置beginTime屬性,則動(dòng)畫立即執(zhí)行),動(dòng)畫執(zhí)行完成后將會(huì)layer的改變恢復(fù)原狀。

3.使用心得

盡量不要設(shè)置removedOnCompletion = false ,因?yàn)榕浜?code>CAAnimationDelegate會(huì)帶來(lái)循環(huán)運(yùn)用的問(wèn)題,如果需要?jiǎng)赢嬐A粼谧詈蟮臓顟B(tài),可以直接設(shè)置Viewcenter屬性在動(dòng)畫結(jié)束的位置Point之所以會(huì)出現(xiàn) 循環(huán)引用 因?yàn)橛捎?code>CAAnimation的delegate使用的strong類型:看一下簡(jiǎn)要的說(shuō)明圖:

CAAnimationDelegate.png

解決有時(shí)視圖會(huì)閃動(dòng)一下的問(wèn)題,我們可以將layer的屬性值設(shè)置為我們的動(dòng)畫最后要達(dá)到的值,然后再給我們的視圖添加layer動(dòng)畫。

4.樣例展示

  • 旋轉(zhuǎn)動(dòng)畫


    旋轉(zhuǎn)動(dòng)畫.gif
  • 位移動(dòng)畫


    位移動(dòng)畫.gif
  • 背景顏色變化動(dòng)畫、背景圖片變化動(dòng)畫、圓角變化動(dòng)畫


    動(dòng)畫集合-1.gif
  • 比例縮放動(dòng)畫


    比例縮放動(dòng)畫.gif
  • size大小縮放、透明值變化動(dòng)畫(可用作閃爍效果)


    size大小縮放、透明值變化動(dòng)畫.gif

5.常用KeyPath總結(jié)

KeyPath值 說(shuō)明 Objective-C Swift 3.0
transform.scale 比例縮放 @(0.8) 0.8
transform.scale.x 縮放寬的比例 @(0.8) 0.8
transform.scale.y 縮放高的比例 @(0.8) 0.8
transform.rotation.x 圍繞x軸旋轉(zhuǎn) @(2 * M_PI) 2 * M_PI
transform.rotation.y 圍繞y軸旋轉(zhuǎn) @(2 * M_PI) 2 * M_PI
transform.rotation.z 圍繞z軸旋轉(zhuǎn) @(2 * M_PI) 2 * M_PI
backgroundColor 背景顏色的變化 (__bridge id _Nullable)([UIColor redColor].CGColor) UIColor.red.cgColor
bounds 大小縮放,中心不變 [NSValue valueWithCGRect:CGRectMake(0, 0, 90, 30)] NSValue(cgRect: CGRect(x: 0, y: 0, width: 90, height: 30))
position 位置(中心點(diǎn)的改變) [NSValue valueWithCGPoint:CGPointMake(60, 240)] NSValue(cgPoint: CGPoint(x: 60, y: 240))
contents 內(nèi)容,比如UIImageView的圖片 ((__bridge id)[UIImage imageNamed:@"to.jpg"].CGImage) UIImage(named: "to")?.cgImage
opacity 透明度 @(0.4) 0.4
contentsRect.size.width 橫向拉伸縮放 @(0.5) 0.5
contentsRect.size.height 縱向拉伸縮放 @(0.5) 0.5

三、CAKeyframeAnimation

CAKeyframeAnimation是核心動(dòng)畫里面的幀動(dòng)畫,它提供了按照指定的一串值進(jìn)行動(dòng)畫,好像拍電影一樣的一幀一幀的效果。

1. 屬性解釋

  • values: 是許多值組成的數(shù)組用來(lái)進(jìn)行動(dòng)畫的。這個(gè)屬性比較特別,只有在path屬性值為nil的時(shí)候才有作用

  • path:路徑,可以指定一個(gè)路徑,讓動(dòng)畫沿著這個(gè)指定的路徑執(zhí)行。

  • cacluationMode:在關(guān)鍵幀動(dòng)畫中還有一個(gè)非常重要的參數(shù),那便是calculationMode計(jì)算模式。其主要針對(duì)的是每一幀的內(nèi)容為一個(gè)座標(biāo)點(diǎn)的情況,也就是對(duì)anchorPointposition 進(jìn)行的動(dòng)畫。當(dāng)在平面座標(biāo)系中有多個(gè)離散的點(diǎn)的時(shí)候,可以是離散的,也可以直線相連后進(jìn)行插值計(jì)算,也可以使用圓滑的曲線將他們相連后進(jìn)行插值計(jì)算。

  1. kCAAnimationLinear calculationMode的默認(rèn)值,r自定義控制動(dòng)畫的時(shí)間(線性)可以設(shè)置keyTimes,表示當(dāng)關(guān)鍵幀為座標(biāo)點(diǎn)的時(shí)候,關(guān)鍵幀之間直接直線相連進(jìn)行插值計(jì)算;
  2. kCAAnimationDiscrete 離散的,就是不進(jìn)行插值計(jì)算,所有關(guān)鍵幀直接逐個(gè)進(jìn)行顯示;
  3. kCAAnimationPaced 節(jié)奏動(dòng)畫自動(dòng)計(jì)算動(dòng)畫的運(yùn)動(dòng)時(shí)間,使得動(dòng)畫均勻進(jìn)行,而不是按keyTimes設(shè)置的或者按關(guān)鍵幀平分時(shí)間,此時(shí)keyTimestimingFunctions無(wú)效;
  4. kCAAnimationCubic 對(duì)關(guān)鍵幀為座標(biāo)點(diǎn)的關(guān)鍵幀進(jìn)行圓滑曲線相連后插值計(jì)算,對(duì)于曲線的形狀還可以通過(guò)tensionValues、continuityValuesbiasValues來(lái)進(jìn)行調(diào)整自定義,這里的數(shù)學(xué)原理是Kochanek–Bartels spline,這里的主要目的是使得運(yùn)行的軌跡變得圓滑,曲線動(dòng)畫需要設(shè)置timingFunctions。
  5. kCAAnimationCubicPaced 看這個(gè)名字就知道和kCAAnimationCubic有一定聯(lián)系,其實(shí)就是在kCAAnimationCubic的基礎(chǔ)上使得動(dòng)畫運(yùn)行變得均勻,就是系統(tǒng)時(shí)間內(nèi)運(yùn)動(dòng)的距離相同,此時(shí)keyTimes以及timingFunctions也是無(wú)效的。
  • keyTimes:一個(gè)包含若干NSNumber對(duì)象值的數(shù)組,用來(lái)區(qū)分動(dòng)畫的分割時(shí)機(jī)。值得注意的是,這些NSNumber對(duì)象的浮點(diǎn)型值在0.0~1.0之間。里面的值后一個(gè)比前一個(gè)要大或者相等。最好的結(jié)果是這個(gè)數(shù)組中的值和values里面的值或者path控制的值對(duì)應(yīng),否則可能會(huì)出現(xiàn)不了你想要的結(jié)果。屬性為應(yīng)用在每一關(guān)鍵幀指定應(yīng)用到每一個(gè)關(guān)鍵幀上的計(jì)時(shí)器。該屬性只在calculationMode屬性被設(shè)置為kCAAnimationLinear,kCAAnimaitonDiscretekCAAnimationCubic時(shí)被使用。它不使用在節(jié)奏動(dòng)畫中。keyTimes定義了應(yīng)用在每一關(guān)鍵幀的時(shí)間點(diǎn)。所有中間值的定時(shí)由定時(shí)函數(shù)控制,定時(shí)函數(shù)允許你對(duì)各個(gè)部分應(yīng)用緩入或緩出曲線定時(shí)。如果你不指定任何定時(shí)函數(shù),動(dòng)畫將會(huì)是線性的。

  • rotationMode:旋轉(zhuǎn)樣式

  1. kCAAnimationRotateAuto 根據(jù)路徑自動(dòng)旋轉(zhuǎn)
  2. kCAAnimationRotateAutoReverse 根據(jù)路徑自動(dòng)翻轉(zhuǎn)

2. 樣例展示

CAKeyframeAnimation路徑動(dòng)畫.gif

四、CATransition

主要用于轉(zhuǎn)場(chǎng)動(dòng)畫從一個(gè)場(chǎng)景以動(dòng)畫的形式過(guò)渡到另一個(gè)場(chǎng)景。

1. 屬性解釋

  • type:轉(zhuǎn)場(chǎng)動(dòng)畫的類型,一個(gè)自定義的轉(zhuǎn)場(chǎng)動(dòng)畫中指定的過(guò)濾器屬性
    | 系統(tǒng)公開(kāi)API | 效果說(shuō)明 | 是否支持方向 |
    | ------------- |:-------------:| -----|
    | kCATransitionFade | 淡出效果 | 是 |
    | kCATransitionMoveIn | 新視圖移動(dòng)到舊視圖上 | 是 |
    | kCATransitionPush | 新視圖推出舊視圖 | 是 |
    | kCATransitionReveal | 移開(kāi)舊視圖顯示新視圖 | 是 |

另外還有一些系統(tǒng)未公開(kāi)的動(dòng)畫效果

["cube", "suckEffect", "rippleEffect", "pageCurl", "pageUnCurl", "oglFlip", "cameraIrisHollowOpen",  "cameraIrisHollowClose", "spewEffect","genieEffect","unGenieEffect","twist","tubey","swirl","charminUltra", "zoomyIn", "zoomyOut", "oglApplicationSuspend"]

效果,就不一一列舉了,可以看下效果圖

  • subtype:轉(zhuǎn)場(chǎng)動(dòng)畫將要去往的方向。
  • startProgress、endProgress: 開(kāi)始和結(jié)束的位置進(jìn)度,數(shù)值介于[0,1]之間,結(jié)束值一定是大于開(kāi)始值的。
動(dòng)畫子類型 說(shuō)明
kCATransitionFromRight 從右側(cè)轉(zhuǎn)場(chǎng)
kCATransitionFromLeft 從左側(cè)轉(zhuǎn)場(chǎng)
kCATransitionFromTop 從頂部轉(zhuǎn)場(chǎng)
kCATransitionFromBottom 從底部轉(zhuǎn)場(chǎng)動(dòng)畫子類型

2. 動(dòng)畫樣例

CATransition路徑動(dòng)畫.gif

五、CASpringAnimation

iOS9才引入的動(dòng)畫類,在以前我們都是使用facebookpop來(lái)做這種彈簧效果,它繼承于CABaseAnimation,用于制作彈簧動(dòng)畫。

1. 參數(shù)說(shuō)明

  • mass:質(zhì)量,影響圖層運(yùn)動(dòng)時(shí)的彈簧慣性,質(zhì)量越大,彈簧拉伸和壓縮的幅度越大,動(dòng)畫的速度變慢,并且波動(dòng)幅度變大。
  • stiffness:剛度系數(shù)(勁度系數(shù)/彈性系數(shù)),剛度系數(shù)越大,形變產(chǎn)生的力就越大,運(yùn)動(dòng)越快。
  • damping:阻尼系數(shù),阻止彈簧伸縮的系數(shù),阻尼系數(shù)越大,停止越快。
  • initialVelocity:初始速率,動(dòng)畫視圖的初始速度大小速率為正數(shù)時(shí),速度方向與運(yùn)動(dòng)方向一致,速率為負(fù)數(shù)時(shí),速度方向與運(yùn)動(dòng)方向相反如果。
  • settlingDuration:結(jié)算時(shí)間 返回彈簧動(dòng)畫到停止時(shí)的估算時(shí)間,根據(jù)當(dāng)前的動(dòng)畫參數(shù)估算通常彈簧動(dòng)畫的時(shí)間使用結(jié)算時(shí)間比較準(zhǔn)確。

2. 例子展示

CASpringAnimation彈簧動(dòng)畫.gif

六、組動(dòng)畫

動(dòng)畫組,是CAAnimation的子類,可以保存一組動(dòng)畫對(duì)象,將CAAnimationGroup對(duì)象加入圖層后,組中所有動(dòng)畫對(duì)象可以同時(shí)并發(fā)運(yùn)行。

1. 參數(shù)說(shuō)明

  • animations屬性:用來(lái)保存一組動(dòng)畫對(duì)象的NSArray
    注意:默認(rèn)情況下,一組動(dòng)畫對(duì)象是同時(shí)運(yùn)行的,也 可以通過(guò)設(shè)置動(dòng)畫對(duì)象的beginTime屬性來(lái)更改動(dòng)畫的開(kāi)始時(shí)間。

2. 例子展示

CAAnimationGroup動(dòng)畫組.gif

七、一些有意思的動(dòng)畫樣例

  • 實(shí)現(xiàn)畫線過(guò)程的動(dòng)畫,雖然很簡(jiǎn)單,但看到很多人都問(wèn)過(guò),效果如下:


    drawLine動(dòng)畫.gif
  • 利用正弦曲線做的,效果還行,相信很多人都做過(guò):


    water動(dòng)畫.gif
  • 左后奉上一個(gè)希望的小火苗,粒子動(dòng)畫,效果很驚人,游戲用的比較多,有興趣,也可以研究下:


    fire動(dòng)畫.gif
  • 魚在魚池游動(dòng)的動(dòng)畫效果:


    fish動(dòng)畫.gif

最后的最后,奉上文章里部分例子的Demo地址:ExamplesForAnimation

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容