使用UIViewPropertyAnimator實現高級動畫

前言

咱們都知道在平常開發中動畫的成分是必不可少的,從那些排行榜單的APP也能看出一款高質量的APP是少不了動畫的加持,早期iOS之因此大放異彩,就是由於iOS把動畫運用到了系統的各個角落。從事iOS的開發者們也知道並使用動畫,使用更多的應該是UIView.animate(withDuration:animations:),其次還有使用CABasicAnimationCAKeyFrameAnimation以及轉場動畫。這些咱們都知道,但更少用到的是這個方式:UIViewPropertyAnimatorbash

UIViewPropertyAnimator對象容許您對視圖進行動畫處理,並在動畫完成以前動態修改它們。使用屬性動畫師,您能夠從頭至尾正常運行動畫,或者您能夠將它們轉換爲交互式動畫並自行控制時間。動畫師對視圖的可動畫屬性進行操做,例如幀,中心,alpha和變換屬性,從您提供的塊建立所需的動畫。閉包

….app

若是使用標準初始化方法之一建立動畫師,則必須經過調用startAnimation()方法顯式啓動動畫。若是要在建立動畫後當即啓動動畫,請使用runningPropertyAnimator方法而不是標準初始值設定項。iview

此類採用UIViewAnimating和UIViewImplicitlyAnimating協議,這些協議定義了啓動,中止和修改動畫的方法。有關這些協議的方法的更多信息,請參閱UIViewAnimating和UIViewImplicitlyAnimating。ide

更多詳細文檔能夠查看官方文檔函數

初探UIViewPropertyAnimator

UIViewPropertyAnimator是iOS 10引入的,用此類建立動畫從上面咱們得知必須手動調用開始動畫方法:動畫

這個是使用UIView的作法:ui

UIView.animate(withDuration: 0.25) {
    view.frame = view.frame.offsetBy(dx: 150, dy: 0)
}
複製代碼

經過UIViewPropertyAnimator實現的作法:spa

let animator = UIViewPropertyAnimator(duration:0.25, curve: .linear) {
     view.frame = view.frame.offsetBy(dx:150, dy:0)
 }
 animator.startAnimation()
複製代碼

從上面看來看區別不大,那還有其餘的特色嗎?確定是有的,特別是在交互式動畫可中斷動畫中。記得在咱們關機的時候出現的"滑動來關機"的交互動畫;還有從底部滑出控制中心等等就是交互式動畫和可中斷動畫就是最好的案例。code

動畫狀態

因爲遵照了UIViewAnimating和UIViewImplicitlyAnimating協議,使用這種方式具備完整的動畫邏輯,例如調用startAnimation、pauseAnimation、stopAnimation等方法將會在inactive、active、stopped的三種狀態間改變。

當動畫開始或暫停的時候爲active狀態,當控件建立完未開始或執行完畢時候的狀態爲inactive,inactive和stopped的區別在於:動畫調用pauseAnimation函數後進行stopped函數,而animator內部會調用finishAnimation(at:)函數來標明此動畫已完畢,而後進入inactive的狀態,最後回調閉包。

動畫選項

建立動畫時常見的是動畫時長、動畫時間曲線(UIViewAnimationCurve已經包含大部分可用的曲線)也能夠進行自定義。

// 設置動畫時間和動畫時間曲線
let animator = UIViewPropertyAnimator(duration: 1.0, curve: .easeOut){
    aView.center = finalPoint
}

// 使用兩個控制點來定義一個貝塞爾時間曲線
let animator = UIViewPropertyAnimator(duration: 1.0, point1: CGPoint(0.1,0.5), point2: CGPoint(0.5, 0.2){
        aView.alpha = 0.0
}

// 實現彈簧效果
let animator = UIViewPropertyAnimator(
               duration: 1.0,
               dampingRatio:0.4){
        AView.center = CGPoint(x:0, y:0)
}

// 動畫延遲
animator.startAnimation(afterDelay:2.0)
複製代碼

動畫回調

UIViewPropertyAnimator 遵照了 UIViewImplicitlyAnimating 協議,這個協議賦予 UIViewPropertyAnimator 許多有趣的特性。例如,除了在初始化期間指定的第一個動畫 block 外,還能夠指定多個動畫 block。值得注意的是,雖然咱們能夠在已經開始的動畫裏添加動畫,可是這會致使剩餘動畫時間來執行新添加的動畫。

// Initialization
let animator = UIViewPropertyAnimator(duration: 2.5, curve: .easeOut){
    aView.alpha = 1.0
}
// Another animation block
animator.addAnimation{ 
    aview.center = aNewPosition
}
// add a animation block
animator.addAnimation{
    aView.center.y = aNewPosition
}
animator.startAnimation()
複製代碼

動畫交互

咱們知道能夠在三個狀態間改變,也就能夠實現動畫的循環。還有一個屬性能夠控制動畫的完成百分比:fractionComplete, 取值範圍[0, 1.0]。能夠經過此值來獲取動畫的百分比,也能夠經過設置此值來控制動畫的百分比。常見的作法經過手勢或一些slider等的時候實時改變並控制動畫。

animator.fractionComplete = progress
複製代碼

還有某些場景須要在動畫結束的時候執行一些任務,UIViewPropertyAnimator容許添加執行完成閉包

// position是一個UIViewAnimatingPosition枚舉:starting、current、end。一般position的值是end
animator.addCompletion { (position) in
    print("Animation completed")
}
複製代碼

高級動畫實踐

相關文章
相關標籤/搜索