跳到主要内容

Core Animation

问题

Core Animation 的核心概念和常用动画 API?

答案

CALayer 与 UIView

UIViewCALayer
框架UIKitQuartzCore
响应事件
动画UIView.animateCAAnimation
关系每个 UIView 持有一个 layer

隐式动画

独立创建的 CALayer 修改属性会自动产生 0.25s 动画:

let layer = CALayer()
layer.backgroundColor = UIColor.red.cgColor
view.layer.addSublayer(layer)

// 以下修改自动有动画
layer.position = CGPoint(x: 200, y: 200)
layer.opacity = 0.5
信息

UIView 的 backing layer 默认禁用隐式动画(在 actionForLayer 中返回 NSNull)。需要用 UIView.animate 包裹才有动画效果。

显式动画

// CABasicAnimation
let anim = CABasicAnimation(keyPath: "position.x")
anim.fromValue = 0
anim.toValue = 300
anim.duration = 1.0
anim.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
layer.add(anim, forKey: "moveX")

// CAKeyframeAnimation(关键帧)
let keyframe = CAKeyframeAnimation(keyPath: "position")
keyframe.values = [
CGPoint(x: 0, y: 0),
CGPoint(x: 100, y: -50),
CGPoint(x: 200, y: 0)
].map { NSValue(cgPoint: $0) }
keyframe.duration = 2.0
layer.add(keyframe, forKey: "path")

// CAAnimationGroup(组合动画)
let group = CAAnimationGroup()
group.animations = [moveAnim, scaleAnim, fadeAnim]
group.duration = 1.5
layer.add(group, forKey: "group")

UIView.animate

UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut) {
view.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
view.alpha = 0.5
} completion: { _ in
view.transform = .identity
view.alpha = 1.0
}

// Spring 弹性动画
UIView.animate(withDuration: 0.5, delay: 0,
usingSpringWithDamping: 0.6,
initialSpringVelocity: 0.5) {
view.center = newCenter
}

常见面试问题

Q1: 动画结束后 layer 回到原位怎么解决?

答案:CA 动画默认操作的是 presentationLayer(视觉效果),不修改 modelLayer(真实属性)。需要:

  • 设置 anim.fillMode = .forwards + anim.isRemovedOnCompletion = false(不推荐,实际属性未变)
  • 或在添加动画前/后手动设置 layer 属性为目标值(推荐)

答案:一个与屏幕刷新同步的定时器,每帧回调一次(60fps = 每 16.67ms)。适合做帧动画、自定义动画引擎。比 Timer 更精准。

相关链接