iOS
UIView
animation
Swift
programming

How to cancel UIView block-based animation?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Classic UIView.animate(...) animations are convenient, but they are not truly cancellable in the same way as UIViewPropertyAnimator. Once started, UIKit drives the underlying Core Animation transaction, and there is no single "cancel and roll back" API for block-based animations.

That does not mean you are stuck. The practical options are to remove layer animations, sync the model layer to the current presentation state, or switch to UIViewPropertyAnimator if you need real pause and cancel control.

What UIView.animate Actually Does

Block-based UIView animation changes model-layer properties and asks UIKit to animate the transition. For example:

swift
1UIView.animate(withDuration: 1.0) {
2    self.boxView.center.x += 200
3    self.boxView.alpha = 0.2
4}

The important detail is that the final property values are already set on the model layer. The animation you see is the visual interpolation between the old and new states.

That is why "cancel" is tricky: removing the animation does not automatically restore the original values.

Basic Interruption: Remove Layer Animations

If you just want the visible motion to stop immediately:

swift
boxView.layer.removeAllAnimations()

This removes the active Core Animation objects from the layer. However, the view may snap either to the start or to the final model value unless you first capture the current presentation state.

Stop Cleanly at the Current Visible Position

To stop the animation without visual jumping, read the presentation layer first, copy its values back to the view, then remove animations:

swift
1func stopAnimation(_ view: UIView) {
2    if let presentation = view.layer.presentation() {
3        view.center = presentation.position
4        view.transform = CATransform3DGetAffineTransform(presentation.transform)
5        view.alpha = Float(presentation.opacity)
6    }
7
8    view.layer.removeAllAnimations()
9}

That pattern works because the presentation layer reflects the current on-screen state during the animation.

Use .beginFromCurrentState for Interrupt-and-Restart Behavior

Sometimes you do not want to cancel so much as replace one animation with another. In that case, .beginFromCurrentState helps UIKit start the new animation from the current visible state:

swift
1UIView.animate(
2    withDuration: 0.4,
3    delay: 0,
4    options: [.beginFromCurrentState, .curveEaseOut],
5    animations: {
6        self.boxView.center.x = 120
7    }
8)

This is often the best solution for gesture-driven or rapidly updated UI where new animations should interrupt old ones smoothly.

When You Really Need Cancel and Pause: UIViewPropertyAnimator

If explicit cancellation is a real requirement, use UIViewPropertyAnimator instead of block-based UIView animation:

swift
1let animator = UIViewPropertyAnimator(duration: 1.0, curve: .easeInOut) {
2    self.boxView.center.x += 200
3    self.boxView.alpha = 0.2
4}
5
6animator.startAnimation()
7
8// Later
9animator.stopAnimation(true)
10animator.finishAnimation(at: .current)

UIViewPropertyAnimator gives you pause, scrub, reverse, and stop behavior that block-based animation APIs do not expose cleanly.

Common Pitfalls

Calling removeAllAnimations() and expecting state rollback

Removing animations stops the visible transition, but it does not automatically restore the original model-layer values. If you care about where the view stops, capture the presentation layer first.

Reading the model layer during animation

During an active animation, the model layer already contains the destination values. If you want the current visible position, read layer.presentation() instead.

Using block-based animations for highly interactive motion

For scrubbing, cancellation, or gesture-controlled progress, block-based UIView animation is usually the wrong tool. UIViewPropertyAnimator is the better abstraction.

Forgetting that multiple view properties may be animating

If position, alpha, transform, and constraints are all changing, you need to restore each relevant property from the presentation state before removing animations.

Summary

  • 'UIView.animate(...) does not have a true high-level cancel API.'
  • 'layer.removeAllAnimations() stops motion, but you may need the presentation layer to preserve the current visible state.'
  • '.beginFromCurrentState is useful when replacing one animation with another.'
  • For real cancellation, pausing, or interactive progress, prefer UIViewPropertyAnimator.
  • Treat model-layer state and presentation-layer state as different things during animation.

Course illustration
Course illustration

All Rights Reserved.