8

这与许多小错误有关,这些小错误可能在一个人的刻板印象中被认为是次要的,但被另一个人认为是主要的。

我越来越注意到的是,当使用所有风格 a 时UIView animateWithDuration:,它实际上会不必要地修改一些东西,比如我的视图的多个属性,做一个简单的隐藏/显示风格动画等等。

在某些情况下,事情似乎很挑剔,例如 UINavigationBar 没有为某个旋转转换正确设置动画,或者标题视图在帧更新时没有与状态栏一起动画,当视图的子层在其父视图的情况下隐式动画不同时属性变化...

其中很多我一直在重新访问,并转换为 CAAnimations,因为它们似乎更易于管理,因为它们实际上并没有修改我的视图的目标属性值。

一个简单的示例是,使用[view setHidden:],然后对其进行动画处理或使其脱离视图,但在动画运行时视图实际上已经可见或隐藏。

另一个是,需要转换/旋转/缩放 UINavigationController 的视图,并使用 CAAnimation 来执行此操作,因为如果我修改 UINavigationController 的视图以及它的任何父视图的转换属性值,UINavigationBar 不会移动到正确的位置.

所以总结这个问题,我来来回回,一直在寻找一个比另一个更适合我的情况的地方,但主要是,我想听听其他人对这些场景的看法,如果有的话深入了解 Apple 提供的内容,让我对自己的方法感觉更好。

提前致谢。

4

1 回答 1

20

归根结底,所有 UIKit 风格的动画都转换为 Core Animation 风格的动画;也就是说,所有内容实际上都是使用 Core Animation 制作的。API 之间的区别主要是为了方便:UIKit 风格的动画函数更新模型值,提交动画以在表示层中反映随着时间的变化。

你还必须小心你正在为 UIKit 说你可以动画的属性设置动画。例如,虽然您可以在技术上为UIScrollViewlikecontentSize和上的属性设置动画contentOffset,但它们不受官方支持,因此您必须潜在地处理副作用。

此外,frame是一种特殊情况,因为它实际上是一个派生属性,由center, transform, and组成bounds(除了anchorPointon CALayer,它UIView不公开)。为视图设置动画frame可能会遇到很多意想不到的问题,通常涉及旋转。Core Animation 没有这个问题,因为frame它不是CALayer. 如果您遇到涉及该视图的仿射变换(例如,缩放、平移、旋转)的奇怪行为,请尝试在 UIKit 样式的动画中使用bounds和。center

确实,在 UIKit 中为某些视图设置动画可能会产生意想不到的副作用或错误,因为除了动画它们之外,您还在更新模型值。另一方面,Core Animation 更灵活一些,因为您可以细粒度地控制它更新模型层或表示层的方式和时间。

但我不同意 UIKit 不必要地修改东西。它会修改需要修改的内容,以提交您请求的动画更改以及更新其模型值。当您为 等属性设置动画时frame,这将在当前运行循环之后隐式调用layoutSubviews()该视图,这可以级联到其他子视图等。

如果你想让 UIKit 在你动画之前执行它的所有布局逻辑,那么在你调用动画块之前setNeedsLayout()调用with 。如果您希望 UIKit 在提交动画的同时实际为整个子视图层次结构的更改价值设置动画,请指定该选项。这将在动画块内立即触发子视图布局,因此这些值也会被动画化。否则,动画更改的模型值将在下一个运行循环中触发布局更新。layoutIfNeeded() UIViewAnimationOptions.layoutSubviews

一般来说,我很少注意到使用 UIKit 风格的动画函数的问题。因此,作为一个在 iOS 上花费大量时间制作动画的人,我想说:

在任何地方都可以使用 UIKit 风格的动画,因为它们真的很方便。当你遇到 UIKit 风格的动画问题或者你需要具体控制如何更新图层的模型和表示值时,应该使用 Core Animation 风格的动画。

于 2016-08-16T01:34:20.670 回答