1. 程式人生 > >iOS開發知識之:Animations 動畫

iOS開發知識之:Animations 動畫

動畫在軟體開發中用的非常頻繁,沒有動畫的軟體,就類似於殭屍;所以對 iOS 常用的動畫進行歸納總結,參考官方文件以及 UIView 和 QuartzCore 文件,受益頗多

 

 


iOS 常用動畫分類

  • UIViewAnimation
  • Core Animation
  • 第三方動畫

iOS 常用動畫思維導圖


動畫的基本屬性

  • Position 位置
  • Opacity 透明度
  • Scale 比例/大小
  • Color 顏色
  • Rotate 旋轉
  • Repeat 重複
  • Spring 彈簧
  • Status 顯示和隱藏狀態

UIViewAnimation

UIView 一般形式動畫

  • beginAnimations:context: 標誌動畫程式碼開始
  • commitAnimations: 標誌動畫程式碼結束,程式會建立新的執行緒,並準備執行動畫
  • setAnimationStartDate: 設定動畫開始時間
  • setAnimationsEnabled: 可以用來開啟或禁止動畫顯示
  • setAnimationDelegate: 設定代理,可以接收到UIView的代理方法
  • setAnimationWillStartSelector: 設定動畫開始前將傳送給代理的方法
  • setAnimationDidStopSelector: 設定動畫停止後將傳送給代理的方法
  • setAnimationDuration: 設定動畫持續時間
  • setAnimationDelay: 設定一段時間,動畫將在這段時間後開始執行
  • setAnimationCurve: 設定動畫曲線,如開始慢,後面快 
    • easeInOut 開始結束慢,中間快
    • easeIn 開始慢, 加速運動
    • easeOut 結束慢,減速運動
    • linear 勻速運動
  • setAnimationRepeatCount: 設定動畫重複次數
  • areAnimationEnabled: 檢查是否已經啟動動畫
  • setAnimationTransition: 設定動畫的過渡效果 
    • none 無過渡效果
    • flipFromLeft 從左邊開始翻轉
    • flipFromRight 從左邊開始翻轉
    • curlUp 向上翻頁
    • curlDown 向下翻頁

程式碼示例

// 開始動畫
UIView.beginAnimations("Identifier", context: nil)
//  設定動畫代理
UIView.setAnimationDelegate(self)
// 通過 #selector 選擇器 新增開始動畫方法
UIView.setAnimationWillStart(#selector(animationAction))
// 通過 #selector 選擇器 新增結束動畫方法
UIView.setAnimationDidStop(#selector(animationAction))
// 設定動畫時間間隔
UIView.setAnimationDuration(1.0)
// 設定動畫延遲
UIView.setAnimationDelay(0)
// 設定動畫開始的時間,預設是現在開始
UIView.setAnimationStart(Date())
// 設定動畫曲線
UIView.setAnimationCurve(.easeInOut)
// 設定動畫重複次數,預設是 0
UIView.setAnimationRepeatCount(0) // 0 無線迴圈
// 自動返回原始狀態
UIView.setAnimationRepeatAutoreverses(false) // default = NO. used if repeat count is non-zero
// 設定動畫的開始是從現在的狀態開始, 預設是 false
UIView.setAnimationBeginsFromCurrentState(false)
// 用來開啟或禁止動畫顯示
UIView.setAnimationsEnabled(true)
// 設定動畫的過渡效果
UIView.setAnimationTransition(.curlUp, for: redView, cache: false)

// 設定 UIView 的動畫屬性
redView.transform = CGAffineTransform(rotationAngle: 90)
redView.transform = CGAffineTransform(scaleX: 0.3, y: 0.3)
redView.transform = CGAffineTransform(translationX: 0, y: 200)

// 動畫的狀態
print(UIView.areAnimationsEnabled)
// 標誌動畫程式碼結束,程式會建立新的執行緒,並準備執行動畫
UIView.commitAnimations()

UIView 閉包式動畫

基礎動畫

UIView.animate(withDuration: TimeInterval,
                 animations: ()->Void)

UIView.animate(withDuration: TimeInterval,
                 animations: ()->Void,
                 completion: ()->Void)

// 帶動畫曲線動畫
UIView.animate(withDuration: TimeInterval,
                      delay: TimeInterval,
                    options: UIViewAnimationOptions,
                 animations: ()->Void,
                 completion: (()->Void)?)

// 帶彈性動畫
UIView.animate(withDuration: TimeInterval,
                      delay: TimeInterval,
     usingSpringWithDamping: 0,
      initialSpringVelocity: 0,
                    options: UIViewAnimationOptions,
                 animations: ()->Void,
                 completion: (()->Void)?)

關鍵幀動畫

UIView.animateKeyframes(withDuration: TimeInterval,
                               delay: TimeInterval,
                             options: UIViewKeyframeAnimationOptions,
                          animations: ()->Void,
                          completion: (()->Void)?)

// 新增幀
UIView.addKeyframe(withRelativeStartTime: Double,
                        relativeDuration: Double,
                              animations: ()->Void)

轉場動畫

UIView.transition(with: UIView,
              duration: TimeInterval,
               options: UIViewAnimationOptions,
            animations: ()->Void,
            completion: (()->Void)?)


// toView added to fromView.superview, fromView removed from its superview
// 檢視的新增和移除動畫
UIView.transition(from: UIView,
                    to: UIView,
              duration: TimeInterval,
               options: UIViewAnimationOptions,
            completion: (()->Void)?)

Core Animation 核心動畫 (基於 CALayer 層級的動畫)

參考資料:

Core Animation

Core Animation Programming Guide


實現步驟:

  • (1) 建立 CAAnimation 子類物件
  • (2) 設定它的引數 (代理、間隔、過渡效果、路徑、)
  • (3) 把這個帶著引數的過渡新增到圖層

CAAnimation

核心動畫基礎類,所有的動畫類基於此類

核心屬性:

  • timingFunction - 一種可選的定時功能,用於定義動畫的節奏 
    • UIViewAnimationCurveEaseInOut — 慢慢的開始,快速的過程,慢慢的結束
    • UIViewAnimationCurveEaseIn — 慢慢的開始,直接加速到結束
    • UIViewAnimationCurveEaseOut — 快速的開始,然後慢慢的結束
    • UIViewAnimationCurveLinear — 勻速變化
  • delegate CAAnimationDelegate 代理,處理動畫過程
  • isRemovedOnCompletion 預設為 true, 動畫完成,自動從渲染樹中移除掉

CAPropertyAnimation

抽象類,基於 CAAnimation,專門用來設定 layer 屬性的動畫類

核心屬性:

  • keyPath 用於描述動畫屬性的關鍵路徑值

CAPropertyAnimation 的 keyPath 動畫屬性總結

屬性 介紹
anchorPoint 錨點
backgroundColor 背景色
borderColor 邊框顏色
borderWidth 邊框寬度
bounds 大小
contents 內容,可以放其他檢視,包括圖片
contentsRect 內容大小
cornerRadius 圓角
filters 濾鏡,模糊
hidden 隱藏
mask 遮擋, 控制內容檢視展示大小
masksToBounds 是否截切掉超過子檢視的部分
opacity 透明度
position 位置
shadowColor 陰影顏色
shadowOffset 陰影偏移
shadowOpacity 陰影的透明度
shadowPath 陰影的路徑
shadowRadius 陰影的圓角
sublayers 子圖層
sublayerTransform 子圖層的變形
transform 變形
zPosition Z軸方向的位置

CABasicAnimation

基於 CAPropertyAnimation,動畫的基礎類

新增的的屬性

  • fromValue 定義了動畫開始時的屬性值
  • toValue 定義了動畫結束時的屬性值

程式碼示例

 let animation = CABasicAnimation(keyPath: "backgroundColor")
 animation.fromValue = UIColor.green.cgColor
 animation.toValue = UIColor.blue.cgColor
 animation.duration = 1.0
 animation.isRemovedOnCompletion = true
 redView.layer.add(animation, forKey: nil)

CASpringAnimation

基於 CABasicAnimation 屬性動畫的彈性動畫

新增的的屬性

  • damping 阻尼彈簧運動的摩擦力, 0.0 ~ 1.0
  • initialVelocity 物體的初始速度
  • mass 模擬物體的重量, > 0, default = 1
  • settlingDuration 沉降時間
  • stiffness 彈簧剛度係數, 0 ~ 100

程式碼示例

let springAnimation = CASpringAnimation(keyPath: "bounds.size")
springAnimation.toValue = NSValue(cgSize: CGSize(width: 250, height: 250))
springAnimation.duration = 1.0
springAnimation.damping = 0.5 // 0.0 to 1.0
springAnimation.initialVelocity = 10
springAnimation.mass = 5
springAnimation.stiffness = 50
redView.layer.add(springAnimation, forKey: nil)

CAKeyframeAnimation

基於屬性動畫,新增關鍵幀動畫功能

新增的屬性

  • valuse 一個物件陣列,指定關鍵幀動畫值來使用
  • path 點屬性依據的路徑
  • keyTimes 一個可選的 NSNumber 物件陣列, 給每個關鍵幀定義時間
  • timingFunctions 一個可選的 CAMediaTimingFunction 物件陣列定義為每個關鍵幀段過渡
  • calculationMode 動畫執行的模式 
    • kCAAnimationLinear
    • kCAAnimationDiscrete
    • kCAAnimationPaced
    • kCAAnimationCubic
    • kCAAnimationCubicPaced
  • rotationMode 決定物體沿路徑動畫路徑上如何旋轉 
    • kCAAnimationRotateAuto
    • kCAAnimationRotateAutoReverse

程式碼示例

let colorKeyframeAnimation = CAKeyframeAnimation(keyPath: "backgroundColor")
colorKeyframeAnimation.values = [UIColor.red.cgColor,
                                 UIColor.green.cgColor,
                                 UIColor.blue.cgColor]
colorKeyframeAnimation.keyTimes = [0, 0.5, 1]
colorKeyframeAnimation.duration = 2
colorKeyframeAnimation.calculationMode = kCAAnimationLinear
redView.layer.add(colorKeyframeAnimation, forKey: nil)

CAAnimationGroup

將多個動畫組合和併發執行 
delegate 和 isRemovedOnCompletion 在動畫的屬性陣列中目前被忽略。 
CAAnimationGroup 的 delegate 接收這些訊息

新增加的屬性

  • animations  CAAnimation 陣列,用於新增多個 CAAnimation 動畫

程式碼示例

let fadeOut = CABasicAnimation(keyPath: "opacity")
fadeOut.fromValue = 1
fadeOut.toValue = 0
fadeOut.duration = 1

let expandScale = CABasicAnimation()
expandScale.keyPath = "transform"
expandScale.valueFunction = CAValueFunction(name: kCAValueFunctionScale)
expandScale.fromValue = [1, 1, 1]
expandScale.toValue = [3, 3, 3]

let fadeAndScale = CAAnimationGroup()
fadeAndScale.animations = [fadeOut, expandScale]
fadeAndScale.duration = 1

redView.layer.add(fadeAndScale, forKey: nil)

CATransition

CAAnimation的子類 
在圖層狀態之間提供動畫轉換的物件 
提供了一個圖層之間的過渡的動畫

CATransition 有一個 type 和 subtype 來標識變換效果

新增加的屬性

  • startProgress 開始的進度 0~1
  • endProgress 結束時的進度 0~1
  • type 轉換型別 
    • kCATransitionFade (default)
    • kCATransitionMoveIn
    • kCATransitionPush
    • kCATransitionReveal
  • subtype 基於運動方向預定義的轉換 
    • kCATransitionFromLeft
    • kCATransitionFromRight
    • kCATransitionFromTop
    • kCATransitionFromBottom
  • filter 濾鏡

程式碼示例

let animation = CATransition()
animation.duration = 1.0
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
// `fade', `moveIn', `push' and `reveal'. Defaults to `fade'
animation.type = kCATransitionReveal
// `fromLeft', `fromRight', `fromTop' and `fromBottom'
animation.subtype = kCATransitionFromTop
animation.isRemovedOnCompletion = true
animation.startProgress = 0.5
redView.layer.add(animation, forKey: nil)

第三方動畫:Facebook POP

POP 是 Facebook 出品的一款很強大的動畫引擎,使用簡潔,效果非常不錯

程式碼示例

if let anim = POPSpringAnimation(propertyNamed: kPOPLayerBounds) {
    anim.toValue = NSValue(cgRect: CGRect(x: 0, y: 0, width: 400, height: 400))
    layer.pop_add(anim, forKey: "size")
}

if let anim = POPBasicAnimation(propertyNamed: kPOPViewAlpha) {
    anim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    anim.fromValue = 0.0
    anim.toValue = 1.0
    view.pop_add(anim, forKey: "fade")
}

// .......

https://blog.csdn.net/mazy_ma/article/details/79025676#關鍵幀動畫