【iOS開發】iOS 動畫詳解

weixin_33670713發表於2017-06-27

關於動畫

在移動開發中,為了提高使用者體驗,會用到一些動畫來提高應用的視覺效果。讓人有眼前一亮的感覺。同時有動畫的過渡過程,會讓應用看起來不是那麼的生硬,更吸引使用者。

UIView動畫

UIView動畫比較簡單,用起來也比較簡單。所以它能實現的功能還是有限的,但是一般的開發中是夠用的。UIView動畫是封裝自CoreAnimation的,下面會講到。

67449-8cbb87656b1c9e54.gif

基本動畫

  • 常規用法begin commit程式碼段
// 第一個引數:動畫的標識
    // 第二個引數:附加引數,會傳送給動畫代理,一般設定為nil就可以了
    [UIView beginAnimations:@"test" context:nil];
    // 動畫執行時間
    [UIView setAnimationDuration:kAnimationDuration];
    // 設定動畫延遲執行時間,預設為0,一般不用設定
    [UIView setAnimationDelay:0];
    // 動畫重複次數
    [UIView setAnimationRepeatCount:1];
    // 動畫是否原路返回
    [UIView setAnimationRepeatAutoreverses:NO];
    
    // 要先設定這個代理,後面設定代理方法才會有效果
    [UIView setAnimationDelegate:self];
    // 這裡的方法也可以是其它的任何方法,如果是這個標準的代理方法,可以不用設定,只設定代理就會執行這個方法
//    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
    // 動畫的時間曲線
    /*UIViewAnimationCurve的列舉值如下:
      UIViewAnimationCurveEaseInOut,//慢進慢出(預設值)
      UIViewAnimationCurveEaseIn,//慢進
      UIViewAnimationCurveEaseOut,//慢出
      UIViewAnimationCurveLinear//勻速
     */
    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
    // 要執行的view的變化
    self.aniView.backgroundColor = [UIColor purpleColor];
    self.aniView.frame = CGRectMake(200, 80, 100, 100);
    // 提交動畫執行
    [UIView commitAnimations];
  • Block用法
// iOS4以後有了block形式的動畫,可以更方便的組織程式碼
    // 只設定動畫時間,要執行的變化
    [UIView animateWithDuration:kAnimationDuration animations:^{
        self.aniView.backgroundColor = [UIColor purpleColor];
        self.aniView.frame = CGRectMake(200, 80, 100, 100);
    }];
    
    [UIView animateWithDuration:kAnimationDuration animations:^{
        
    } completion:^(BOOL finished) {
        // 動畫執行完後的回撥
    }];
    
    
    // options 可以設定多個。
    [UIView animateWithDuration:kAnimationDuration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
        self.aniView.backgroundColor = [UIColor purpleColor];
        self.aniView.frame = CGRectMake(200, 80, 100, 100);
    } completion:^(BOOL finished) {
        NSLog(@"動畫執行完了");
    }];

Spring動畫(帶彈簧效果)

iOS7 以後引入的Spring動畫,iOS8的時候Apple開放的Spring動畫的API,開發者可以藉助這個API很簡單的實現帶有彈簧的動畫效果了。

用法:

[UIView animateWithDuration:kAnimationDuration // 動畫持續時間
                          delay:0 // 動畫延遲執行的時間
         usingSpringWithDamping:0.2 // 震動效果,範圍0~1,數值越小震動效果越明顯
          initialSpringVelocity:10 // 初始速度,數值越大初始速度越快
                        options:UIViewAnimationOptionCurveEaseIn // 動畫的過渡效果
                     animations:^{
                         //執行的動畫
                         self.aniView.backgroundColor = [UIColor purpleColor];
                         self.aniView.frame = CGRectMake(200, 80, 100, 100);
                     }
                     completion:^(BOOL finished) {
                         // 動畫執行完後的回撥
                     }];            

Core Animation動畫

Core Animation翻譯過來就是核心動畫,它是iOS平臺和MAC OS平臺動畫的核心元件。上面的UIView動畫就是封裝自Core Animation。它有一組非常強大的API,可以實現各種各樣炫酷的動畫效果。在日常開發中,一般的動畫效果都可以用UIView層封裝好的動畫實現,但是有一些動畫還是得用Core Animation來實現,例如:一些複雜的直播動畫效果、自定義一些圓形進度條、一些路徑類的自定義view等。

CAAnimation 的動畫是作用在layer上,每個view在建立時,會預設建立一個用於顯示的layer。所以要熟練運用Core Animation 必須對CALayer有一定的瞭解,下面這張圖(網上盜的)是CALayer的一些屬性。

67449-c8f21d9219d431ca.jpg

類結構

Core Animation中開發直接用到的動畫類就兩個CABasicAnimation``CAKeyFrameAnimation,下面是Core Animation的類結構圖:

67449-bea58a11139b07ab.jpg

CAAnimation 的一些屬性,子類會用到:

  • timingFunction 動畫速度
    • kCAMediaTimingFunctionLinear 線性,勻速
    • kCAMediaTimingFunctionEaseIn 漸進,逐漸進入,然後加速完成
    • kCAMediaTimingFunctionEaseOut 漸出,動畫全速進入,然後緩慢完成
    • kCAMediaTimingFunctionEaseInEaseOut 漸進漸出
  • removedOnCompletion 預設為YES,代表動畫執行完畢後就從圖層上移除,圖形會恢復到動畫執行前的狀態。如果想讓圖層保持顯示動畫執行後的狀態,那就設定為NO,不過還要設定fillMode

CAMediaTiming協議 相關屬性:

  • beginTime 動畫的開始時間(如果超過的duration,那麼動畫不會開始)
  • duration 動畫的持續時間
  • speed 動畫的速度
  • repeatCount 重複次數,預設為0,無限重複可以設定為HUGE_VALF或者MAXFLOAT
  • repeatDuration 動畫重複時間,預設為0
  • fillMode 決定當前物件在非active時間段的行為。(要想fillMode有效,最好設定removedOnCompletion = NO)
  • fillMode型別:
    • kCAFillModeRemoved 這個是預設值,也就是說當動畫開始前和動畫結束後,動畫對layer都沒有影響,動畫結束後,layer會恢復到之前的狀態
    • kCAFillModeForwards 當動畫結束後,layer會一直保持著動畫最後的狀態
    • kCAFillModeBackwards 在動畫開始前,只需要將動畫加入了一個layer,layer便立即進入動畫的初始狀態並等待動畫開始。
    • kCAFillModeBoth 這個其實就是上面兩個的合成,動畫加入後開始之前,layer便處於動畫初始狀態,動畫結束後layer保持動畫最後的狀態

CAPropertyAnimation 這是一個抽象類,不能直接使用,要實現動畫,一般用它的兩個子類,相關屬性:

  • keyPath 指定接收層動畫的關鍵路徑(入門篇提供了部分keyPath,敬請參考)
  • cumulative 下一次動畫執行是否接著剛才的動畫,預設為false
  • additive 如何處理多個動畫在同一時間段執行的結果,若為true,同一時間段的動畫合成為一個動畫,預設為false。(使用 * CAKeyframeAnimation 時必須將該屬性指定為 true ,否則不會出現期待的結果)

CABasicAnimation(基礎動畫)

67449-6a9758ccb32fa916.gif
67449-e4250dbaa4384d12.gif

相關屬性:

  • fromValue 開始的值
  • toValue 結束時的值
  • byValue 動畫過程中的值

關於這三個屬性的設定有如下幾種結果:

  • 設定fromValue和toValue,keyPath屬性值在fromValue與toValue之間漸變
  • 設定fromValue和byValue,keyPath屬性值在fromValue與(fromValue+byValue)之間漸變
  • 設定byValue和toValue,keyPath屬性值在(toValue-byValue)與toValue之間漸變
  • 只設定fromValue,keyPath屬性值在fromValue與圖層對應當前值之間漸變
  • 只設定toValue,keyPath屬性值在圖層對應當前值與toValue之間漸變
  • 只設定byValue,keyPath屬性值在圖層對應當前值與(圖層對應當前值+toValue)之間漸變

NOTICE: 為了防止衝突,在指定了toValue時不需要byValue、而指定了byValue也不需要指定toValue。
value的值可以設定為CATransform3D的物件,實現3D動畫效果!

CAKeyFrameAnimation

示例:

67449-8e35928ef2c06dad.gif

相關屬性:

  • values 存放“關鍵幀”,動畫會一次到達關鍵幀指定的值,並自動生成中間動畫。
  • path 路徑,可以設定一個CGPathRef的路徑,讓圖層按照路徑移動,因此只對anchorPosition和position起作用,當設定了path會忽略掉values中的值。
  • keyTimes 指定到達每個關鍵幀的時間,與values對應,不設定就是平分。
  • timingFunctions 指定到達每一幀的速度,度values對應,可以不設定。

CATransition

67449-ed405eb191dd82f0.gif

屬性:

  • type 動畫的型別
  • subtype 動畫過度方向(可自行檢視相關字串)

type的型別:

  • 基本效果

    • kCATransitionFade 漸入漸出效果
    • kCATransitionMoveIn 移入效果
    • kCATransitionPush 推入效果
    • kCATransitionReveal 截開效果
  • 私有API(可安全使用):

    • cube 方塊
    • suckEffect 三角
    • rippleEffect 水波
    • pageCurl 上翻頁
    • pageUnCurl 下翻頁
    • oglFlip 上下翻轉
    • cameralrisHollowOpen 鏡頭快門開
    • cameralrisHollowClose 鏡頭快門關

CAAnimationGroup

  • animations
    陣列,裡面存放動畫(動畫可以是,基本動畫、關鍵幀動畫等其他動畫)裡面存放的動畫可以不設定時間和重複次數,統一在CAAnimationGrop物件中設定。陣列中動畫的duration可以單獨設定,還可以設定陣列中動畫的開始時間,來控制動畫單個動畫在組動畫中的執行時間,但是時間不能超過組動畫的時間,如果超過,該動畫不會執行。

可以在github上找到以上動畫示例Demo

相關文章