When is it appropriate to use Core Animation over UIView animation in common cases

此生再无相见时 提交于 2019-12-05 13:53:27

At the end of the day, all UIKit-style animations are converted to Core Animation-style animations; that is, everything is actually animated using Core Animation. The difference between the APIs is mostly one of convenience: UIKit-style animation functions update the model value, committing an animation to reflect that change over time in the presentation layer.

You have to also be careful that you're animating properties that UIKit says you can animate. For example, while you can technically animate properties on UIScrollView like contentSize and contentOffset, they aren't officially supported, so you have to potentially deal with side effects.

In addition, frame is a special case because it's actually a derived property, composed of center, transform, and bounds (in addition to anchorPoint on CALayer, which UIView does not expose). Animating a view's frame can have a whole host of unintended problems, usually involving rotation. Core Animation doesn't have this problem, because frame is not an explicitly-animatable property on CALayer. Try to use bounds and center in UIKit-style animations if you're encountering weird behavior involving the affine transform (e.g., scale, translate, rotation) of that view.

It's true that animating certain views in UIKit might have unintended side effects or bugs because you're updating model values in addition to animating them. Core Animation, on the other hand, is a little more flexible, because you have fine-grained control over how and when it updates either the model layer or the presentation layer.

But I would disagree that UIKit is modifying things unnecessarily. It modifies what it needs to modify in order to commit the animated changes you request as well as updating its model values. When you're animating properties such as frame, this is going to implicitly invoke layoutSubviews() on that view after the current run loop, which can cascade to other subviews and so on.

If you want UIKit to perform all its layout logic before you animate, then call setNeedsLayout() along with layoutIfNeeded() before you invoke an animation block. If you'd like UIKit to actually animate the entire subview hierarchy's worth of changes at the same time that your animation is committed, specify the UIViewAnimationOptions.layoutSubviews option. This will trigger subview layout immediately, within the animation block, so those values are animated as well. Otherwise, the model values that are changed by your animation will trigger layout updates on the next run loop.

In general, I rarely notice issues using UIKit-style animation functions. So as someone who has spent an extensive amount of time animating on iOS, I would say:

Use UIKit-style animations in every place you can, since they're really convenient. Core Animation-style animations should be used when you run into problems with UIKit-style animations or if you need specific control over how a layer's model and presentation values need to be updated.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!