iOS14開發-動畫

介紹

動畫每每能起到加強用戶體驗的做用,在 iOS 開發中,咱們可使用 UIKit 提供的動畫來實現,簡稱 UIView 動畫。UIView 動畫實質上是對 Core Animation(核心動畫)的封裝,提供簡潔的動畫 API。swift

普通動畫

  • API
// 最完整
open class func animate(withDuration duration: TimeInterval, delay: TimeInterval, options: UIView.AnimationOptions = [], animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) open class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) // 最簡單 open class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void) 複製代碼
  • 參數含義
    • duration:動畫持續時間。
    • delay:動畫延遲執行的時間。
    • UIView.AnimationOptions:動畫的過渡效果,能夠組合使用。
    • animations:執行的動畫。
    • completion:動畫執行完畢後的操做。

案例

// 兩個參數
// 將須要執行動畫的語句放入閉包便可
UIView.animate(withDuration: 0.5) {
    view.backgroundColor = UIColor.red
}

// 閉包中能夠同時執行多個屬性的動畫
UIView.animate(withDuration: 0.5) {
    view.backgroundColor = UIColor.red
    view.center.y += 100
    view.alpha = 0
}

// 三個參數
UIView.animate(withDuration: 0.5) {
    view.backgroundColor = UIColor.red
} completion: { _ in
    print("動畫執行完畢")
}

// 五個參數
UIView.animate(withDuration: 0.5, delay: 0.5, options: .curveLinear) {
    view.backgroundColor = UIColor.red
} completion: { _ in
    print("動畫執行完畢")
}

// 放在performWithoutAnimation閉包中就會不執行動畫
UIView.animate(withDuration: 0.5) {
    view.backgroundColor = UIColor.red
    
    UIView.performWithoutAnimation {
        view.alpha = 0.2
    }
}
複製代碼

UIView.AnimationOptions

常見的AnimationOptions有:api

  • curveEaseInOut:時間曲線,慢速開始,而後加速,最後減速(默認值)。
  • curveEaseIn:時間曲線,慢速開始,以後愈來愈快。
  • curveEaseOut:時間曲線,快速開始,以後愈來愈慢。
  • curveLinear:時間曲線,勻速。
  • repeat:指定這個選項後,動畫會無限重複。
  • autoreverse:往返動畫,從開始執行到結束後,又從結束返回開始。
  • preferredFramesPerSecond30:指定動畫刷新頻率爲30fps。
  • preferredFramesPerSecond60:指定動畫刷新頻率爲60fps。

中止動畫

view.layer.removeAllAnimations()
複製代碼

彈簧動畫

  • 又稱 Spring 動畫。
  • API
open class func animate(withDuration duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping dampingRatio: CGFloat, initialSpringVelocity velocity: CGFloat, options: UIView.AnimationOptions = [], animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) 複製代碼
  • 參數含義
    • duration:動畫持續時間。
    • delay:動畫延遲執行的時間。
    • dampingRatio:震動效果,範圍 0~1,數值越小震動效果越明顯。
    • velocity:初始速度,數值越大初始速度越快。
    • UIView.AnimationOptions:動畫的過渡效果,能夠組合使用。(與普通動畫相似)。
    • animations:執行的動畫。
    • completion:動畫執行完畢後的操做。

案例

// 三個動畫進行對比
UIView.animate(withDuration: 3.0, delay: 0, usingSpringWithDamping: 0.1, initialSpringVelocity: 0, options: .curveEaseIn, animations: {
    blueView.center.y += 300
}, completion: nil)

UIView.animate(withDuration: 3.0, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 10, options: .curveEaseIn, animations: {
    greenView.center.y += 300
}, completion: nil)

UIView.animate(withDuration: 3.0, delay: 0, usingSpringWithDamping: 0.9, initialSpringVelocity: 20, options: .curveEaseIn, animations: {
    redView.center.y += 300
}, completion: nil)
複製代碼

轉場動畫

  • API
// 單個視圖的過渡效果
open class func transition(with view: UIView, duration: TimeInterval, options: UIView.AnimationOptions = [], animations: (() -> Void)?, completion: ((Bool) -> Void)? = nil) // 從舊視圖轉到新視圖的動畫效果 open class func transition(from fromView: UIView, to toView: UIView, duration: TimeInterval, options: UIView.AnimationOptions = [], completion: ((Bool) -> Void)? = nil) 複製代碼
  • 參數含義
    • view:產生動畫的視圖。
    • fromView:動畫過程當中,fromView 會從父視圖中移除。
    • toView:fromView 消失之後, toView 添加到父視圖中。
    • duration:動畫持續時間。
    • UIView.AnimationOptions:動畫的過渡效果,能夠組合使用。(以 transition 開頭的纔有過渡效果)。
    • animations:執行的動畫。
    • completion:動畫執行完畢後的操做。

案例

  • 方式一
UIView.transition(with: self.redView, duration: 2.0, options: .transitionCurlUp, animations: { 
    let orangeView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))    
    orangeView.center = self.redView.center
    orangeView.backgroundColor = UIColor.orange  
    self.redView.addSubview(orangeView)    
}, completion: nil)
複製代碼
  • 方式二
let orangeView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
orangeView.backgroundColor = UIColor.orange
UIView.transition(from: self.redView, to: orangeView, duration: 2.0, options: .transitionFlipFromRight, completion: nil)
複製代碼

座標轉換

思考:在方式一中設置的orangeView.center = self.redView.center並無實現預期的效果,爲何?markdown

由於redVieworangeView參考的不是同一個座標系,須要進行座標轉換閉包

座標轉換分爲兩種,一種是 CGPoint 轉換,一種是 CGRect 轉換。ide

CGPoint轉換
// self.view(from參數)的self.redView.center(point參數)轉換到self.redView(調用者)中
orangeView.center = self.redView.convert(self.redView.center, from: self.view)
// self.view(調用者)將self.redView.center(point參數)轉換到self.redView(to參數)中
orangeView.center = self.view.convert(self.redView.center, to: self.redView)
複製代碼
CGRect轉換
// self.redView(from參數)的orangeView.frame(rect參數)轉換到self.view(調用者)中
orangeView.frame = self.view.convert(orangeView.frame, from: self.redView)
// self.view(調用者)將self.redView.frame(rect參數)轉換到self.redView(to參數)中
self.redView.frame = self.view.convert(self.redView.frame, to: self.redView)
複製代碼

關鍵幀動畫

  • API
open class func animateKeyframes(withDuration duration: TimeInterval, delay: TimeInterval, options: UIView.KeyframeAnimationOptions = [], animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) open class func addKeyframe(withRelativeStartTime frameStartTime: Double, relativeDuration frameDuration: Double, animations: @escaping () -> Void) 複製代碼
  • 參數含義
    • duration:動畫持續的總時間。
    • delay:動畫延遲執行的時間。
    • UIView.KeyframeAnimationOptions:動畫的過渡效果,能夠組合使用。
    • animations:執行的關鍵幀動畫。
    • completion:動畫執行完畢後的操做。
    • frameStartTime:動畫開始的時間(佔總時間的比例)。
    • relativeDuration:動畫持續時間(佔總時間的比例)。
    • animations:執行的幀動畫。

案例

class ViewController: UIViewController {
    @IBOutlet var leaf: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        UIView.animateKeyframes(withDuration: 6.0, delay: 0, options: .calculationModeCubic, animations: {
            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.1, animations: {
                self.leaf.center = CGPoint(x: 108, y: 260)
            })

            UIView.addKeyframe(withRelativeStartTime: 0.1, relativeDuration: 0.1, animations: {
                self.leaf.center = CGPoint(x: 138, y: 340)
            })

            UIView.addKeyframe(withRelativeStartTime: 0.2, relativeDuration: 0.1, animations: {
                self.leaf.center = CGPoint(x: 168, y: 420)
            })

            UIView.addKeyframe(withRelativeStartTime: 0.3, relativeDuration: 0.1, animations: {
                self.leaf.center = CGPoint(x: 200, y: 490)
            })

            UIView.addKeyframe(withRelativeStartTime: 0.4, relativeDuration: 0.1, animations: {
                self.leaf.center = CGPoint(x: 248, y: 570)
            })

            UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.1, animations: {
                self.leaf.center = CGPoint(x: 278, y: 630)
            })

            UIView.addKeyframe(withRelativeStartTime: 0.6, relativeDuration: 0.1, animations: {
                self.leaf.center = CGPoint(x: 308, y: 690)
            })

            UIView.addKeyframe(withRelativeStartTime: 0.7, relativeDuration: 0.1, animations: {
                self.leaf.center = CGPoint(x: 318, y: 770)
            })

            UIView.addKeyframe(withRelativeStartTime: 0.8, relativeDuration: 0.1, animations: {
                self.leaf.center = CGPoint(x: 328, y: 860)
            })

            UIView.addKeyframe(withRelativeStartTime: 0.9, relativeDuration: 0.1, animations: {
                self.leaf.transform = CGAffineTransform(rotationAngle: CGFloat(Float.pi * 0.25))
            })
        }, completion: nil)
    }
}
複製代碼

UIView.KeyframeAnimationOptions

常見的KeyframeAnimationOptions有:動畫

  • calculationModeLinear:運算模式,連續。
  • calculationModeDiscrete:運算模式,離散。
  • calculationModePaced:運算模式,均勻執行。
  • calculationModeCubic:運算模式,平滑。
  • calculationModeCubicPaced:運算模式,平滑均勻。
  • repeat:指定這個選項後,動畫會無限重複。
  • autoreverse:往返動畫,從開始執行到結束後,又從結束返回開始。
相關文章
相關標籤/搜索