Core Animation is the underlying technology that makes iOS animations smooth and performant. Let’s explore how it works.

The Layer Tree

Every UIView has a corresponding CALayer. Animations happen at the layer level.

let view = UIView()
view.layer.cornerRadius = 10
view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOffset = CGSize(width: 0, height: 2)
view.layer.shadowOpacity = 0.3
view.layer.shadowRadius = 4

Implicit vs Explicit Animations

Implicit Animations

Automatic, triggered by property changes:

UIView.animate(withDuration: 0.3) {
    view.alpha = 0.5
    view.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
}

Explicit Animations

Controlled animations using CABasicAnimation:

let animation = CABasicAnimation(keyPath: "opacity")
animation.fromValue = 1.0
animation.toValue = 0.0
animation.duration = 0.3
animation.timingFunction = CAMediaTimingFunction(name: .easeIn)
view.layer.add(animation, forKey: "fadeOut")

Keyframe Animations

let keyframeAnimation = CAKeyframeAnimation(keyPath: "position")
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 100, y: 100))
path.addLine(to: CGPoint(x: 200, y: 50))
keyframeAnimation.path = path.cgPath
keyframeAnimation.duration = 2.0
keyframeAnimation.fillMode = .forwards
keyframeAnimation.isRemovedOnCompletion = false
view.layer.add(keyframeAnimation, forKey: "movement")

Animation Groups

let group = CAAnimationGroup()
group.animations = [positionAnimation, opacityAnimation, scaleAnimation]
group.duration = 1.0
group.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
view.layer.add(group, forKey: "combined")

Performance Tips

  1. Avoid implicit animations on layer properties - Use explicit when possible
  2. Use shouldRasterize for complex layers
  3. Keep layer trees shallow
  4. Use CADisplayLink for frame-by-frame control

iOS Animation Demo

Understanding Core Animation gives you low-level control over iOS interactions.