UIView.animate — 在 iOS 中对 UIView 属性进行动画的主要方法,通过 UIKit 中的带有 duration、delay 和 options 的块实现。该方法动画化 frame、alpha、transform、backgroundColor 和其他可动画属性。本文介绍了语法、参数、实际示例以及 UIKit 动画的内部结构。
要点
UIView.animate — UIView 类的静态方法,于 iOS 4(2010)中引入。它为 UIView 的可动画属性提供声明式 API:frame、bounds、center、alpha、transform、backgroundColor。该方法接收一个包含属性更改的块(闭包)——系统自动为每个更改的属性创建 CABasicAnimation。
块语法取代了旧的 beginAnimations/commitAnimations(iOS 2-3),并成为 UIKit 中的动画标准。UIView.animate 动画在主线程上执行,不会阻塞 UI。默认情况下,动画持续时间为 0.25 秒,使用 easeInOut 曲线。
根据 Apple WWDC 2023 的数据,新项目中推荐的动画方式是使用 SwiftUI 的 .animation() 和 .transition() 修饰符,但 UIKit.animate 仍然是支持 iOS 16 及更低版本以及复杂自定义过渡的主要工具。
UIView.animate 提供三个关键参数:duration(持续时间,以秒为单位)、delay(开始前的延迟)和 options(UIView.AnimationOptions 位掩码集合)。Options 包括 curve(easeInOut、easeIn、easeOut、linear)、repeat(重复)、autoreverse(自动反转)、allowUserInteraction、beginFromCurrentState 和 overrideInheritedDuration。
| 参数 | 类型 | 描述 |
|---|---|---|
| duration | TimeInterval | 动画持续时间,以秒为单位(Double 类型) |
| delay | TimeInterval | 动画开始前的延迟 |
| options | UIView.AnimationOptions | 位掩码:curve、repeat、autoreverse、layoutSubviews |
| animations | () -> Void | 包含可动画属性更改的块 |
| completion | (Bool) -> Void | 动画完成后的闭包 |
options 参数通过数组组合:[.curveEaseOut, .repeat, .autoreverse]。带有 repeat 和 autoreverse 的动画会将 View 平滑地恢复到初始状态并无限重复。对于有限次数的重复,请使用 animateKeyframes。
弹簧动画 添加了物理弹簧效果:对象不仅从 A 点移动到 B 点,而且会越过目标并产生衰减振荡。参数:usingSpringWithDamping(阻尼 0-1,其中 0 为最大振荡)和 initialSpringVelocity(弹簧的初始速度)。
Apple 建议对自然的 UI 动画使用 0.4-0.8 范围内的 usingSpringWithDamping。值 0.5 会产生明显的回弹而不会产生橡胶感。initialSpringVelocity = 1.0 对应于 1 pt/秒的速度。为 0 时,动画从静止状态开始。
// 弹簧动画和关键帧示例
import UIKit
class AnimatedView: UIView {
func springBounce() {
// 带阻尼的弹簧动画
UIView.animate(
withDuration: 0.8,
delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 1.0,
options: [.allowUserInteraction],
animations: {
self.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
self.alpha = 0.7
},
completion: { _ in
UIView.animate(withDuration: 0.3) {
self.transform = .identity
self.alpha = 1.0
}
}
)
}
func slideIn(from offset: CGFloat) {
self.transform = CGAffineTransform(translationX: offset, y: 0)
self.alpha = 0.0
UIView.animate(
withDuration: 0.6,
delay: 0.1,
options: [.curveEaseOut]
) {
self.transform = .identity
self.alpha = 1.0
}
}
}UIView.animateKeyframes 允许将动画分成多个步骤(关键帧),每个步骤具有自己的相对时间和持续时间。addKeyframe(withRelativeStartTime:relativeDuration:) 方法接受相对于动画总持续时间的 0 到 1 之间的时间值。
关键帧动画适用于多步骤效果:按钮脉冲(放大→暂停→返回)、元素的顺序出现、具有中间状态的复杂变形。每个关键帧可以通过 options 拥有自己的动画曲线。
// 带有复杂序列的关键帧动画
func complexPulse() {
UIView.animateKeyframes(withDuration: 2.0, delay: 0, options: [.repeat]) {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.25) {
self.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
self.alpha = 0.5
}
UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.25) {
self.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
self.alpha = 0.8
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) {
self.transform = .identity
self.alpha = 1.0
}
}
}
// 带嵌套闭包的动画
func animateCardTransition() {
UIView.animate(withDuration: 0.4, delay: 0, options: [.curveEaseOut]) {
self.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
} completion: { _ in
UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseIn]) {
self.transform = .identity
}
}
}在底层,UIView.animate 通过 Core Animation(CAAnimation)将动画委托给每个 UIView 的 CALayer。当您在动画块内更改 frame 时,系统会为相应图层的 position 和 bounds 属性创建 CABasicAnimation。如果更改 alpha ——则为图层的 opacity 属性创建 CABasicAnimation。
Core Animation 使用单独的渲染服务器进程(iOS 上的 backboardd),以 120 Hz(ProMotion)的频率处理动画。UIView.animate 不会阻塞主线程——属性更改被发送到渲染服务器,该服务器在没有应用程序参与的情况下插值帧。
根据 Apple 的数据,通过 UIView.animate 进行的动画在 60 FPS 下每个更改的图层会产生约 2-3% 的 CPU 开销。对于大量动画(同时 20+ 个对象),建议使用 CATransaction 和手动图层管理。
使用 Xcode Debug View Hierarchy 调试和可视化 UIKit 动画——它显示每个图层上的活动 CAAnimations、它们的持续时间、曲线和当前状态。了解 Core Animation 的内部结构有助于避免复杂动画中的性能问题,并在 UIView.animate 和直接使用 CABasicAnimation 之间选择最佳方法。
使用 Xcode Debug View Hierarchy 调试和可视化 UIKit 动画——它显示每个图层上的活动 CAAnimations、它们的持续时间、曲线和当前状态。了解 Core Animation 的内部结构有助于避免复杂动画中的性能问题,并在 UIView.animate 和直接使用 CABasicAnimation 之间选择最佳方法。
常见问题
可动画属性 UIView:frame、bounds、center、alpha、transform(CGAffineTransform)、backgroundColor。更改 Auto Layout 约束时的 layoutIfNeeded() 更改也可动画化。其余属性不能通过 UIView.animate 动画化——对于它们,请使用 CALayer 或 CADisplayLink。
UIView.animate 执行从当前状态到目标状态的单个动画。UIView.animateKeyframes 将总持续时间分成多个具有不同相对开始和持续时间的步骤(关键帧)。关键帧适用于多步骤序列。
UIView.animate 动画在渲染服务器(backboardd)中处理——这是一个单独的 iOS 进程。主线程仅发送属性的初始值和最终值。帧插值通过 Core Animation 在 GPU 上以高达 120 FPS 的频率执行。
在 UIView 上调用 layer.removeAllAnimations()——这将删除在底层创建的所有 CAAnimations。要获得更精确的控制,请使用 CATransaction 和通过 CAAnimation.keyPath 的动画标识符。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。