iOS Animation — UIViewPropertyAnimator

Kuang Lin
2 min readJan 15, 2020

--

Executing animations sequentially and stop the one is animating..

UIViewPropertyAnimator is the recommended animation framework of iOS.

In the past, we use UIView.animate(duration:animations:) to do the animating works for us.

For UIViewPropertyAnimator can do more.

Let’s see how it works:

For UIView.animate(duration:animations:completion:) :

UIView.animate(withDuration: 0.4, animations: {
// Do the animation
}, completion: { isComplete in
// Do the completion work
})

For UIViewPropertyAnimator :

let animations: () -> () = {//do something}
let completion: (UIViewAnimatingPosition) -> () = {position in //do something}
let animator = UIViewPropertyAnimator(duration: 0.4,
curve: .easeInOut)
animator.addAnimations(animations)
animator.addCompletion(completion)
animator.startAnimation()

The Animation States (UIViewAnimatingState)

  1. inactive
  2. active
  3. stopped

The most important thing about this state is that:

You can only call animator.startAnimation() when the animator.state == inactive

Otherwise it throws exception.

Animation States changes

The following is the functions that a UIViewPropertyAnimator triggers and the corresponding state.

Create an animator — inactive.

animator.startAnimate() or animator.pauseAnimation()active

animator.stopAnimation(true)inactive.

animator.stopAnimation(false)stopped.

So if you want to write a function that takes animation blocks and execute the input animations one at a time, and stops the old one if there’s a new animation, here’s the sample:

private let animator = UIViewPropertyAnimator(duration: 0.4, curve: .easeInOut)func animateSomething(animations: () -> () completion: ((UIViewAnimatingPosition) -> ())?) {

if animator.state == .active {
animator.stopAnimation(false)
}

if animator.state == .stopped {
animator.finishAnimation(at: .start)
}
animator.addAnimations(animations)
animator.addCompletion(completetionsb)
animator.startAnimation()
}
  1. First we set animator as a property so we can make all the animations comes into our function handled by one instance.
  2. We check if the current state is active because we want only one animation. If it’s active, we stop the animation and set the state to stopped
  3. If the state is stopped, we should finishAnimation before we addAnimations to avoid the app crash. And the finishAnimation() will trigger the completion block of your function.
  4. Prepare a new animation by calling addAnimations() and addCompletion()
  5. Call startAnimation() to start a new animation.

--

--

Kuang Lin
Kuang Lin

Responses (1)