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
)
- inactive
- active
- stopped
The most important thing about this state is that:
You can only call
animator.startAnimation()
when theanimator.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()
}
- First we set animator as a property so we can make all the animations comes into our function handled by one instance.
- 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
- If the state is stopped, we should
finishAnimation
before weaddAnimations
to avoid the app crash. And thefinishAnimation()
will trigger the completion block of your function. - Prepare a new animation by calling
addAnimations()
andaddCompletion()
- Call
startAnimation()
to start a new animation.