Working with UIKit Animations
1. Using UIView.animate Methods
| Method | Description | Parameters | Notes |
|---|---|---|---|
| UIView.animate(withDuration:animations:) | Animates changes to one or more views | duration: TimeInterval, animations: () -> Void |
Basic animation method with no easing |
| UIView.animate(withDuration:delay:options:animations:completion:) | Animates changes with more control over timing and options | duration: TimeInterval, delay: TimeInterval, options: UIView.AnimationOptions, animations: () -> Void, completion: ((Bool) -> Void)? |
Supports options like curveEaseInOut, repeat |
| UIView.animate(withDuration:animations:completion:) | Animates with optional completion handler | duration: TimeInterval, animations: () -> Void, completion: ((Bool) -> Void)? |
Simple animation with optional callback |
Example: Basic UIView Animation
UIView.animate(withDuration: 0.5) {
view.backgroundColor = .red
view.frame.origin.x += 100
}
Example: UIView Animation with Options
UIView.animate(withDuration: 1.0, delay: 0.2, options: [.curveEaseInOut, .repeat]) {
view.alpha = 0.5
}
2. Animating View Properties
| Property | Type | Description | Animatable |
|---|---|---|---|
| frame | CGRect |
Rectangle defining view's location and size | Yes |
| bounds | CGRect |
Rectangle defining view's internal coordinate system | Yes |
| center | CGPoint |
Center point of the view in its superview's coordinate system | Yes |
| alpha | CGFloat |
Opacity level from 0.0 (transparent) to 1.0 (opaque) | Yes |
| backgroundColor | UIColor |
Background color of the view | Yes |
| transform | CGAffineTransform |
Affine transformation to apply to the view | Yes |
Example: Animating Frame Property
UIView.animate(withDuration: 1.0) {
view.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
}
Example: Animating Transform Property
UIView.animate(withDuration: 0.5) {
view.transform = CGAffineTransform(rotationAngle: .pi / 4)
}
3. Using Animation Curves
| Curve Type | Description | Usage |
|---|---|---|
| linear | Constant speed animation | CAMediaTimingFunction(name: .linear) |
| easeIn | Starts slow, speeds up | CAMediaTimingFunction(name: .easeIn) |
| easeOut | Starts fast, slows down | CAMediaTimingFunction(name: .easeOut) |
| easeInOut | Starts and ends slow, speeds up in the middle | CAMediaTimingFunction(name: .easeInOut) |
| custom | Custom curve using control points | CAMediaTimingFunction(controlPoints: (0.5, 0.5, 0.5, 0.5)) |
Example: Custom Animation Curve
let animation = CABasicAnimation(keyPath: "position.x")
animation.fromValue = 100
animation.toValue = 300
animation.timingFunction = CAMediaTimingFunction(controlPoints: (0.2, 0.8, 0.4, 1.0))
layer.add(animation, forKey: "move")
4. Chaining Animations
UIKit provides several ways to chain animations together, allowing for complex animation sequences. The most common approaches involve using completion handlers or combining multiple animations with specific timing.
| Method | Description | Usage |
|---|---|---|
| UIView.animate(withDuration:delay:options:animations:completion:) | Animates changes to view properties with a completion handler that can trigger another animation. | |
| UIView.animateKeyframes(withDuration:delay:options:animations:completion:) | Allows defining keyframe-based animations with multiple stages, useful for chaining. | |
Example: Sequential Animation Chain
UIView.animate(withDuration: 0.3, animations: {
button.backgroundColor = .red
}) { _ in
UIView.animate(withDuration: 0.3, animations: {
button.transform = CGAffineTransform(rotationAngle: .pi / 4)
}) { _ in
UIView.animate(withDuration: 0.3, animations: {
button.alpha = 0.0
})
}
}
Note: When chaining animations, always ensure that each animation's completion handler triggers the next one to maintain a smooth sequence.
5. Using Spring Animations
| Property | Value | Description |
|---|---|---|
| dampingRatio | 0.0 to 1.0 |
Controls how much the animation bounces. Lower values mean more bounce. |
| initialVelocity | CGVector |
Initial velocity of the animation in points per second. |
| mass | 1.0 |
Mass of the animated object, affecting how it responds to forces. |
| stiffness | 0.0 to 1000.0 |
How stiff the spring is; higher values make the animation more rigid. |
Example: Spring Animation
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var viewToAnimate: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let springAnimation = UIViewPropertyAnimator(duration: 0.5, dampingRatio: 0.5) {
self.viewToAnimate.center.x += 100
}
springAnimation.startAnimation()
}
}
Note: Spring animations are ideal for UI elements that need to feel natural and responsive, like when a button is pressed or a view slides in.
6. Using Keyframe Animations
Keyframe animations in UIKit allow you to define a sequence of animation steps that interpolate between different states. They are particularly useful for creating complex, multi-step animations.
| Property | Description | Values |
|---|---|---|
| keyframeAnimation | Defines a keyframe animation using a sequence of values and timing functions. | CAKeyframeAnimation |
| values | An array of values that the animation will transition through. | [Any] |
| keyTimes | Defines the timing of each keyframe, normalized between 0.0 and 1.0. | [NSNumber] |
| timingFunctions | Defines the timing function for each keyframe segment. | [CAMediaTimingFunction] |
Example: Basic Keyframe Animation
let animation = CAKeyframeAnimation(keyPath: "position.x")
animation.values = [100, 200, 300, 400]
animation.keyTimes = [0.0, 0.33, 0.66, 1.0]
animation.timingFunctions = [
CAMediaTimingFunction(name: .easeInEaseOut),
CAMediaTimingFunction(name: .easeInEaseOut),
CAMediaTimingFunction(name: .easeInEaseOut)
]
view.layer.add(animation, forKey: "keyframeAnimation")
Example: Keyframe Animation with Rotation
let rotationAnimation = CAKeyframeAnimation(keyPath: "transform.rotation.z")
rotationAnimation.values = [0, 1.57, 3.14, 4.71]
rotationAnimation.keyTimes = [0.0, 0.33, 0.66, 1.0]
rotationAnimation.duration = 2.0
view.layer.add(rotationAnimation, forKey: "rotationKeyframe")
Note: Keyframe animations are powerful for creating complex motion paths or state transitions. They allow fine-grained control over timing and interpolation between values.
7. Animating Constraints
| Property | Values | Description |
|---|---|---|
| constant | CGFloat |
The offset value of the constraint |
| multiplier | CGFloat |
A scaling factor applied to the constraint's constant |
| isActive | Bool |
Enables or disables the constraint |
Example: Animating Constraint Changes
class ViewController: UIViewController {
@IBOutlet weak var redView: UIView!
@IBOutlet weak var heightConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
animateConstraint()
}
func animateConstraint() {
UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseInOut) {
self.heightConstraint.constant = 200
self.view.layoutIfNeeded()
}
}
}
Note:
layoutIfNeeded() must be called inside the animation block to ensure layout updates are animated.
Key Points
- Constraints must be modified inside an animation block to animate changes
layoutIfNeeded()is required to trigger the layout update- Use
UIView.animateorUIViewPropertyAnimatorfor smooth transitions
8. Using UIViewPropertyAnimator
UIViewPropertyAnimator is a powerful class in UIKit that allows you to create and control animations with fine-grained control over timing, velocity, and interaction. It's particularly useful for creating complex animations that can be paused, reversed, or modified during runtime.
| Property | Description | Notes |
|---|---|---|
| duration | The total duration of the animation in seconds. | Defaults to 0.25 seconds |
| timingParameters | Defines the timing curve of the animation. | Can be set to UITimingCurve or custom parameters |
| isRunning | Indicates whether the animation is currently running. | Read-only property |
| fractionComplete | The fraction of the animation that has completed (0.0 to 1.0). | Can be used for interactive control |
Example: Basic UIViewPropertyAnimator Usage
let animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeInOut) {
view.backgroundColor = .red
}
animator.startAnimation()
Example: Controlling Animation Progress
let animator = UIViewPropertyAnimator(duration: 1.0, curve: .easeInOut) {
view.center.x += 100
}
animator.fractionComplete = 0.5 // Pause at halfway
animator.startAnimation()
Example: Reversing Animation
let animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeInOut) {
view.alpha = 0.0
}
animator.startAnimation()
animator.isReversed = true // Reverse the animation
animator.continueAnimation(withTimingParameters: nil, durationFactor: 1.0)
Note:
UIViewPropertyAnimator is ideal for creating interactive animations where the user can influence the animation's progress, such as in drag-and-drop or swipe gestures.
9. Creating Custom Transitions
Example: Custom Transition with UIViewControllerAnimatedTransitioning
import UIKit
class CustomTransition: NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.5
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let toView = transitionContext.view(forKey: .to),
let fromView = transitionContext.view(forKey: .from) else { return }
let containerView = transitionContext.containerView
containerView.addSubview(toView)
toView.alpha = 0.0
UIView.animate(withDuration: transitionDuration(using: transitionContext),
delay: 0,
options: .curveEaseInOut) {
toView.alpha = 1.0
} completion: { _ in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
}
| Property | Description | Notes |
|---|---|---|
| transitionDuration | Duration of the animation in seconds | Must return a positive value |
| animateTransition | Method to perform the actual animation | Called by the system during transition |
Note: The
UIViewControllerContextTransitioning object provides access to views and container view for custom transitions.Key Steps to Implement Custom Transitions
- Implement
UIViewControllerAnimatedTransitioningprotocol - Define transition duration and animation behavior
- Use
transitionContextto access views and container - Call
completeTransitionto finish the transition
10. Using Core Animation
| Property | Value | Description |
|---|---|---|
| layer | CALayer |
Core Animation layer associated with the view |
| animation | CAAnimation |
Base class for all Core Animation objects |
| keyPath | String |
Specifies the property to animate (e.g., "position.x") |
| duration | CFTimeInterval |
Duration of the animation in seconds |
| timingFunction | CAMediaTimingFunction |
Defines the pacing of the animation (e.g., easeInEaseOut) |
Example: Basic Core Animation
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var animatedView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let animation = CABasicAnimation(keyPath: "position.x")
animation.fromValue = animatedView.layer.position.x
animation.toValue = animatedView.layer.position.x + 100
animation.duration = 2.0
animatedView.layer.add(animation, forKey: "moveAnimation")
}
}
Example: Keyframe Animation
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var animatedView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let animation = CAKeyframeAnimation(keyPath: "position.x")
animation.values = [0, 50, 100, 150, 200]
animation.keyTimes = [0.0, 0.25, 0.5, 0.75, 1.0]
animation.duration = 3.0
animatedView.layer.add(animation, forKey: "keyframeAnimation")
}
}
Note: Core Animation is built on
CALayer, which provides a more granular control over animations than UIKit's built-in methods.
Core Animation Overview
- CALayer is the foundation of Core Animation in iOS.
- CAAnimation is the base class for all animations.
- keyPath specifies which property to animate (e.g.,
"position.x","opacity"). - CABasicAnimation is used for simple, linear animations.
- CAKeyframeAnimation allows for more complex, multi-step animations.