最终,所有 UIKit 风格的动画都会转换为 Core Animation 风格的动画;也就是说,所有内容实际上都是使用 Core Animation 进行动画处理的。 API 之间的区别主要在于便利性:UIKit 风格的动画函数更新模型值,提交动画以反映表示层中随时间的变化。
您还必须小心,您正在对 UIKit 表示可以设置动画的属性进行动画处理。例如,虽然您可以在技术上为属性设置动画UIScrollView
like contentSize
and contentOffset
,它们没有得到官方支持,因此您必须应对潜在的副作用。
此外,frame
是一个特殊情况,因为它实际上是一个派生属性,由center
, transform
, and bounds
(此外anchorPoint
on CALayer
, which UIView
不暴露)。动画视图frame
可能会出现一系列意想不到的问题,通常涉及轮换。 Core Animation 不存在这个问题,因为frame
不是显式可动画化的属性CALayer
。尝试使用bounds
and center
在 UIKit 风格的动画中,如果您遇到涉及该视图的仿射变换(例如缩放、平移、旋转)的奇怪行为。
确实,在 UIKit 中对某些视图进行动画处理可能会产生意想不到的副作用或错误,因为除了对它们进行动画处理之外,您还要更新模型值。另一方面,核心动画更加灵活,因为您可以精细控制它更新模型层或表示层的方式和时间。
但我不同意 UIKit 进行不必要的修改。它修改需要修改的内容,以便提交您请求的动画更改以及更新其模型值。当您对属性进行动画处理时,例如frame
,这将隐式调用layoutSubviews()
在当前运行循环之后的该视图上,它可以级联到其他子视图等。
如果您希望 UIKit 在制作动画之前执行所有布局逻辑,请调用setNeedsLayout()
随着layoutIfNeeded()
before您调用动画块。如果您希望 UIKit 在提交动画的同时实际对整个子视图层次结构的更改进行动画处理,请指定UIViewAnimationOptions.layoutSubviews
选项。这将立即在动画块内触发子视图布局,因此这些值也会被动画化。否则,动画更改的模型值将在下一个运行循环中触发布局更新。
一般来说,我很少注意到使用 UIKit 风格的动画函数的问题。因此,作为一个在 iOS 上花费了大量时间制作动画的人,我会说:
在任何可以使用的地方使用 UIKit 风格的动画,因为它们真的很方便。当您遇到 UIKit 风格的动画问题或者需要对如何更新图层的模型和表示值进行特定控制时,应使用核心动画风格的动画。