什么时候使用 UIView 动画、CABasicAnimation 和 UIViewPropertyAnimator?

When to use UIView animation, CABasicAnimation and UIViewPropertyAnimator?

我想知道在哪些情况下我们应该使用它们中的任何一个作为最合适的?

在下面的博客https://www.hackingwithswift.com/ios10中,在"Animations revisited"部分写的例子,我们可以使用"CABasicAnimation"重新应用相同的需求,意思是暂停和恢复动画吗?

据我所知,当我们使用 UIView.animate(...) 方法时,它 return 是一个空白,因此我们无法在动画完成之前控制它,因为当我们进入 UIViewPropertyAnimator 时,我们没有得到一个 return 值来处理(另外,这里我们有 "isRunning" 来检查动画的进度。) 同样在 CABasicAnimation 中,我们没有对 运行 动画进行任何进度检查。 如果我的假设是错误的,请纠正我。 谢谢。

TLDR

  • UIView 的动画方法允许简单和基本的 UIView 属性动画,代码占用空间很小。
  • Core Animation 允许对底层的属性进行动画处理。
  • UIViewPropertyAnimator 允许 UIView 属性的复杂动态动画。

背景

所有这些 API 都很棒,而且它们的用例都略有不同。在进入它们之前,最好了解一下

  1. iOS 上的所有动画都是 运行 使用核心动画。 UIKit 基于块的动画方法只是一个方便的功能。
  2. 虽然 UIKit 和 Core Animation 都提供动画支持,但它们允许访问视图层次结构的不同部分。

使用 UIKit,动画是使用 UIView 对象执行的。使用 UIKit 的动画可用的属性是:

  • frame
  • bounds
  • center
  • transform
  • alpha
  • backgroundColor
  • contentStretch

虽然 Core Animation 允许访问视图的底层,但暴露了一组不同的属性,如下所述(值得注意的是,由于视图和层错综复杂地链接在一起,对视图层的更改会影响视图本身):

  • 层的大小和位置
  • 执行变换时使用的中心点
  • 图层或其子图层的 3D 变换 space
  • 在图层层次结构中添加或删除图层
  • 图层相对于其他同级图层的 Z 顺序
  • 图层的阴影
  • 图层边框(包括图层边角是否圆角)
  • 在调整大小操作期间拉伸的图层部分
  • 图层的不透明度
  • 位于层边界之外的子层的裁剪行为
  • 图层的当前内容
  • 图层的光栅化行为

请参阅 this Apple Developer document 了解更多相关信息。


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,this 是一篇很棒的文章(不是我写的)。


UIViewPropertyAnimator

添加于iOS10,顾名思义这是另一个基于视图的动画API。它与 UIView 的动画方法有几点不同,主要是它支持交互式动画并允许动态修改动画。您可以暂停、倒带或擦洗动画,还可以随时添加更多动画块或在播放动画时反转动画,这使它非常强大。当我希望动画由用户控制时,我会使用它。通过在 animator 对象上设置 fractionComplete 属性 来进行擦洗,它可以很容易地连接到平移手势识别器或力触摸识别器(甚至是使用 KVO 的键)。

如前所述,您还可以存储对 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()

}

值得注意的是,您实际上可以在 UIViewPropertyAnimator 动画块中使用 UIView.animateUIView.animateKeyframes,如果您觉得需要同时使用两者的话。

如果你想要更详细的例子UIViewPropertyAnimator,我写了一个关于它的小教程here