18

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

在下面的博客https://www.hackingwithswift.com/ios10中,“Animations revisited”部分中编写的示例,我们可以使用“CABasicAnimation”重新应用相同的要求,即暂停和恢复动画吗?

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

4

1 回答 1

50

TLDR

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

背景

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

  1. iOS 上的所有动画都使用 Core Animation 运行。UIKit 的基于块的动画方法只是一个方便的特性。
  2. 虽然 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.animateKeyframesUIViewPropertyAnimator

如果你想要一个更详细的例子,我在这里UIViewPropertyAnimator写了一个小教程。

于 2017-04-03T17:19:56.760 回答