Skip to main content

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 Alpha Property

UIView.animate(withDuration: 0.5) {
    view.alpha = 0.0
}

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.animate(withDuration: 0.5, delay: 0, options: [], animations: {
    view.alpha = 0.0
}) { _ in
    UIView.animate(withDuration: 0.5, animations: {
        view.frame.origin.x = 100
    })
}
UIView.animateKeyframes(withDuration:delay:options:animations:completion:) Allows defining keyframe-based animations with multiple stages, useful for chaining.
UIView.animateKeyframes(withDuration: 2.0, delay: 0, options: [], animations: {
    UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5) {
        view.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
    }
    UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) {
        view.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
    }
}) { _ in
    print("Animation sequence complete")
}

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.animate or UIViewPropertyAnimator for 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 UIViewControllerAnimatedTransitioning protocol
  • Define transition duration and animation behavior
  • Use transitionContext to access views and container
  • Call completeTransition to 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.

Was this article helpful?