Swift — 說說 UIViewPropertyAnimator
讓我們來認識一下什麼是 UIViewPropertyAnimator 吧!
✒︎ 前言:
其實 UIViewPropertyAnimator
已經在 iOS 10 的時候就可以使用了,只是一直沒有機會去使用到它,依然使用 UIView.animate
舊方法土法煉鋼,直到某次專案上使用到 UIViewPropertyAnimator
之後,發現多了許多特性以及功能,在製作動畫上面比之前的方式好用許多。
而官方文件後來也不推薦開發者使用 UIView.animate
的方式來執行動畫,而是使用 UIViewPropertyAnimator
來執行動畫。接下來就讓我們看看他有什麼特殊的內容及功能吧!
✒︎ UIViewPropertyAnimator:
‣ 概論:
使用 UIViewPropertyAnimator
可以為 View
的變動來製作動畫,並且在完成動畫之前動態修改它們。使用屬性動畫器時,你可以從頭到尾正常的運行動畫或是將它們變成交互式動畫並且自己控制時間。而屬性動畫器會對 View
的可動畫屬性進行操作,例如:frame
、center
、alpha
以及 transform
屬性,由你所提供的程式區塊來創建所需的動畫。
在創建屬性動畫器時,請指定以下內容:
- 包含修改一個或多個
View
屬性的程式碼區塊。 - 時序曲線(timing curve)。用於定義動畫在其運行過程中的速度。
- 動畫的持續時間(以秒為單位)。
- 動畫完成時執行的可選程式碼區塊。
在動畫程式碼區塊中,將可設置動畫的屬性值設置為你希望該 View
反映的最終值,例如:如果你想要淡出 View
,可以在程式碼區塊中將其 alpha
屬性設置為 0。屬性動畫器創建一個動畫,將該屬性的值從其初始值調整至你在程式碼區塊中所指定的新值。
屬性值更改的速度由創建屬性動畫器時指定的時序曲線控制。屬性動畫器包括內建 UIKit 動畫曲線的支持,例如:線性(linear)、緩進(ease-in)和緩出(ease-out)。你還可以使用三次方貝茲曲線(cubic Bezier curve)或彈性函數來控制動畫的時間。
如果使用標準初始化方式之一來創建動畫器,則必須透過調用 startAnimation
方法顯式開始動畫。如果想要在創建動畫器後立即開始動畫,請使用 runningPropertyAnimator
方法,而不是標準初始化器。
UIViewPropertyAnimator
採用了 UIViewAnimating
與 UIViewImplicitlyAnimating
協議,它們定義了開始、停止和修改動畫的方法。有關這些協議的方法的更多資訊,請參考以下內容:
‣ 動態修改動畫:
屬性動畫器讓你可以用程式碼的方式來控制動畫的時間點和執行。具體來說你可以:
- 開始,暫停,繼續和停止動畫。可參考
UViewAnimating
協議方法。 - 在原有動畫開始後,使用
addAnimations
方法添加動畫區塊。 - 透過修改
fractionComplete
屬性來清理(Scrub)暫停的動畫。 - 使用
isReversed
屬性修改動畫的方向。 - 透過暫停動畫,並且使用
continueAnimation
方法來完成動畫,來修改部分完成的動畫的時間點和持續時間。
大多數的基本行為由 UIViewPropertyAnimator
所採用的 UIViewAnimating
協議的屬性控制。使用這些方法和屬性可以開始、暫停、繼續和停止動畫。你還可以使用它們在動畫中進行清理並改變其方向。使用此類的方法和屬性可以修改動畫區塊本身並更新時間點資訊。
‣︎ 初始化屬性動畫器:
在使用 UIViewPropertyAnimator
來製作動畫時,我們可以根據我們需求不同使用以下幾種來創建它方法,特別注意 runningPropertyAnimator
是一個 class function 而不是 initializer:
// 使用內建的 UIKit 時序曲線初始化動畫器。
init(duration: TimeInterval, curve: UIView.AnimationCurve, animations: (() -> Void)?)// 使用三次方貝茲時序曲線初始化動畫器。
init(duration: TimeInterval, controlPoint1: CGPoint, controlPoint2: CGPoint, animations: (() -> Void)?)
Initializes the animator object with a cubic Bézier timing curve.// 使用基於彈性的時序曲線初始化動畫器。
init(duration: TimeInterval, dampingRatio: CGFloat, animations: (() -> Void)?)// 使用自定義時序曲線初始化動畫器。
init(duration: TimeInterval, timingParameters: UITimingCurveProvider)
Initializes the animator object with a custom timing curve object.// 創建並且返回一個動畫器,該動畫器立即執行動畫。
class func runningPropertyAnimator(withDuration: TimeInterval, delay: TimeInterval, options: UIView.AnimationOptions, animations: () -> Void, completion: ((UIViewAnimatingPosition) -> Void)?) -> Self
‣ 修改動畫:
而我們對於屬性動畫器的修改或調整也是相當容易,我們可以透過以下幾個方法,來添加、調整動畫,或是添加動畫完成後的程式碼區塊到動畫器中:
// 添加動畫到動畫器。
func addAnimations(() -> Void)// 添加帶有延遲的動畫到動畫器。
func addAnimations(() -> Void, delayFactor: CGFloat)// 添加完成程式碼區塊到動畫器。
func addCompletion((UIViewAnimatingPosition) -> Void)// 調整暫停動畫的時間點和持續時間。
func continueAnimation(withTimingParameters: UITimingCurveProvider?, durationFactor: CGFloat)
✒︎ 後記:
這次關於 UIViewPropertyAnimator
的簡單介紹就到這邊,可以看得出來使用屬性動畫器的方式會比使用 UIView.animate
的方式強大,光是在添加動畫區塊這段就不太會像之前一樣容易寫出 callback hell 的程式碼,而是使用 addAnimations
的方式添加,加上他還能夠靈活控制動畫這點實在是大勝 UIView.animate
這種老舊方法。之後會再針對 UIViewPropertyAnimator
來做一些實做文章,畢竟我還是很熱愛做動畫的 xDD。