使用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")
}
复制代码

高级动画实践

相关文章
相关标签/搜索