UIKitSeniorMCQ
What is `UIViewPropertyAnimator` and how does it differ from `UIView.animate`?
Test your knowledge:
Explanation & Code
Answer:
UIViewPropertyAnimator is an object that owns an animation, which makes that animation interruptible, reversible, and scrubbable. You can pause it mid-flight, read and set fractionComplete, reverse its direction, and resume it — UIView.animate is fire-and-forget: once started you cannot inspect it, retarget it, or drive it from a gesture.
Code Example:
// Fire-and-forget — still the right call for simple, uninterruptible animations
UIView.animate(withDuration: 0.3) {
self.card.alpha = 1
}
// Interactive, gesture-driven sheet
final class SheetController: UIViewController {
private var animator: UIViewPropertyAnimator?
@objc func handlePan(_ gesture: UIPanGestureRecognizer) {
let translation = gesture.translation(in: view).y
switch gesture.state {
case .began:
animator = UIViewPropertyAnimator(duration: 0.4, dampingRatio: 0.8) {
self.sheet.transform = CGAffineTransform(translationX: 0, y: -400)
}
animator?.pauseAnimation() // pause so we can scrub it manually
case .changed:
animator?.fractionComplete = -translation / 400 // drive it with the finger
case .ended:
let velocity = gesture.velocity(in: view).y
animator?.isReversed = velocity > 0 // flick down → play backwards
animator?.continueAnimation(
withTimingParameters: UISpringTimingParameters(dampingRatio: 0.8),
durationFactor: 0
)
default: break
}
}
}
// Custom timing curves and staged work
let animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeOut) {
self.header.transform = .init(scaleX: 1.2, y: 1.2)
}
animator.addAnimations({ self.header.alpha = 0 }, delayFactor: 0.5) // second half only
animator.addCompletion { position in
print(position == .end ? "finished" : "reversed or stopped")
}
animator.startAnimation()
Key Points:
- Only
UIViewPropertyAnimatorgives youfractionComplete,pauseAnimation(),isReversed, andstopAnimation(_:)— the building blocks of any interactive transition - Hold a strong reference to the animator; a local one deallocates and the animation stops
stopAnimation(false)freezes the presentation values, thenfinishAnimation(at:)commits them —stopAnimation(true)leaves the model layer untouched- Reach for
UIView.animatewhen the animation just needs to run to completion; the extra API isn't free in complexity
References:
Rate your understanding: