精选文章

07. 动画实战

2019-02-11 · 动画

07. 动画实战

动画的关键是:用对动画类型、避免布局抖动、保证动画状态一致。下面按常用场景展开。

一、UIView 动画(最常用)

UIView.animate(withDuration: 0.25,
               delay: 0,
               options: [.curveEaseInOut]) {
    self.cardView.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
    self.cardView.alpha = 0.8
} completion: { _ in
    self.cardView.transform = .identity
    self.cardView.alpha = 1
}

适合透明度、位移、缩放、旋转等 UI 变化。

二、弹簧动画

UIView.animate(withDuration: 0.6,
               delay: 0,
               usingSpringWithDamping: 0.7,
               initialSpringVelocity: 0.5,
               options: []) {
    self.panel.transform = .identity
}

usingSpringWithDamping 越小弹性越强。

三、Core Animation(Layer 级动画)

1. 基础动画

let anim = CABasicAnimation(keyPath: "opacity")
anim.fromValue = 0
anim.toValue = 1
anim.duration = 0.3

layer.opacity = 1 // 必须更新最终状态
layer.add(anim, forKey: "fadeIn")

注意:动画只作用于“展示层”,最终状态要写回 layer

2. 关键帧动画

let anim = CAKeyframeAnimation(keyPath: "position")
anim.values = [
    CGPoint(x: 40, y: 40),
    CGPoint(x: 80, y: 60),
    CGPoint(x: 120, y: 40)
]
anim.duration = 0.5
anim.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
layer.add(anim, forKey: "pathMove")

四、UIViewPropertyAnimator(交互动画)

let animator = UIViewPropertyAnimator(duration: 0.4, curve: .easeInOut) {
    self.drawerView.transform = CGAffineTransform(translationX: 0, y: -300)
}

animator.startAnimation()
animator.pauseAnimation()
animator.fractionComplete = 0.5
animator.continueAnimation(withTimingParameters: nil, durationFactor: 0.6)

适合手势驱动的动画,如抽屉、卡片拖拽。

五、避免动画抖动

  • 动画中不要频繁触发布局
  • 使用 transform 优先于修改 frame
  • 列表内动画尽量简化
// 不建议频繁改 frame
// 建议改 transform
view.transform = CGAffineTransform(translationX: 0, y: -12)

六、交互手势 + 动画结合

@objc func handlePan(_ pan: UIPanGestureRecognizer) {
    let translation = pan.translation(in: view)
    let progress = min(max(translation.y / 300, 0), 1)

    switch pan.state {
    case .changed:
        animator.fractionComplete = progress
    case .ended, .cancelled:
        animator.continueAnimation(withTimingParameters: nil, durationFactor: 1)
    default:
        break
    }
}

七、动画性能要点

  • 优先使用 opacitytransform
  • 避免在动画中触发大量重绘
  • 对复杂阴影或蒙版保持谨慎

动画写得稳定,体验会非常明显。关键是让“动画驱动状态”,而不是“动画制造状态”。

JJ

作者简介

专注于内容创作、产品策略与设计实践。欢迎交流合作。

上一篇 下一篇