TLDR
- UIView 的动画方法允许 UIView 属性的简单和基本的动画,几乎没有代码占用。
- Core Animation 允许对底层的属性进行动画处理。
- UIViewPropertyAnimator 允许 UIView 属性的复杂和动态动画。
背景
所有这些 API 都很棒,而且它们的用例都略有不同。在进入它们之前,最好了解一下
- iOS 上的所有动画都使用 Core Animation 运行。UIKit 的基于块的动画方法只是一个方便的特性。
- 虽然 UIKit 和 Core Animation 都提供动画支持,但它们可以访问视图层次结构的不同部分。
使用 UIKit,动画是使用UIView
对象执行的。使用 UIKit 可用于动画的属性是:
frame
bounds
center
transform
alpha
backgroundColor
contentStretch
虽然 Core Animation 提供了对视图底层的访问权限,但暴露了一组不同的属性,如下所述(值得注意的是,由于视图和层错综复杂地链接在一起,对视图层的更改会影响视图本身):
- 图层的大小和位置
- 执行转换时使用的中心点
- 在 3D 空间中对层或其子层的转换
- 从层层次结构中添加或删除层
- 层相对于其他兄弟层的 Z 顺序
- 图层的阴影
- 图层的边框(包括图层的角是否圆角)
- 在调整大小操作期间拉伸的图层部分
- 图层的不透明度
- 位于层边界之外的子层的剪切行为
- 图层的当前内容
- 图层的光栅化行为
有关此内容的更多信息,请参阅此 Apple Developer 文档。
UIView 的动画方法
在我看来,这些仍然是最容易使用的。非常直接的 API,不会占用太多代码。我将它用于简单的即发即弃动画(例如在选择时弹出按钮),或者当我想要制作复杂的关键帧动画时,因为它的关键帧支持非常好。
例子:
UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseOut, animations: {
button.transform = .init(scaleX: 1.1, y: 1.1)
}
核心动画
使用起来可能不那么直接,但是当你想要动画层属性而不是视图属性时,你需要它,如上所述。这些示例包括圆角半径、阴影和边框。
例子:
CATransaction.begin()
CATransaction.setAnimationDuration(0.5)
CATransaction.timingFunction = .init(name: .easeOut)
let cornerAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.cornerRadius))
cornerAnimation.fromValue = 0.0
cornerAnimation.toValue = 10.0
button.layer.add(cornerAnimation, forKey: #keyPath(CALayer.cornerRadius))
CATransaction.commit()
有关 Core Animation 的更详细介绍,这是一篇很棒的文章(不是我写的)。
UIViewPropertyAnimator
在 iOS 10 中添加,顾名思义,这是另一个基于视图的动画 API。它与 UIView 的动画方法有一些不同,主要是它支持交互式动画并允许动态修改动画。您可以暂停、倒带或擦洗动画,还可以随时添加更多动画块或在播放时反转动画,这使得它非常强大。当我希望动画由用户控制时,我会使用它。擦洗通过fractionComplete
在动画对象上设置一个属性来工作,它可以很容易地连接到平移手势识别器或强制触摸识别器(甚至使用 KVO 的键)。
如前所述,您还可以存储对 a 的引用UIViewPropertyAnimator
并在动画期间更改其动画或完成块。
例子:
// Create an animation object with an initual color change animation
let animator = UIViewPropertyAnimator(duration: duration, curve: .linear) {
button.backgroundColor = .blue
}
// At any point during the runtime, we can amend the list of animations like so
animator.addAnimations {
button.transform = .init(scaleX: 1.1, y: 1.1)
}
animator.startAnimation()
}
值得注意的是,如果您觉得需要同时使用两者,您可以在动画块中实际使用UIView.animate
和。UIView.animateKeyframes
UIViewPropertyAnimator
如果你想要一个更详细的例子,我在这里UIViewPropertyAnimator
写了一个小教程。