Why do docs indicate CALayer animations must be in

2019-04-27 08:14发布

问题:

I am currently reading Apple's Core Animation Guide, where I found the following passage regarding layer-backed views in iOS:

If you want to use Core Animation classes to initiate animations, you must issue all of your Core Animation calls from inside a view-based animation block. The UIView class disables layer animations by default but reenables them inside animation blocks. So any changes you make outside of an animation block are not animated.

Just below the quote, the documentation includes the following code listing:

[UIView animateWithDuration:1.0 animations:^{
   // Change the opacity implicitly.
   myView.layer.opacity = 0.0;

   // Change the position explicitly.
   CABasicAnimation* theAnim = [CABasicAnimation animationWithKeyPath:@"position"];
   theAnim.fromValue = [NSValue valueWithCGPoint:myView.layer.position];
   theAnim.toValue = [NSValue valueWithCGPoint:myNewPosition];
   theAnim.duration = 3.0;
   [myView.layer addAnimation:theAnim forKey:@"AnimateFrame"];
}];

which implies that both implicit and explicit animations on CALayers backing UIViews must be placed within an animation block.

However, I have found this to be patently untrue. Specifically, I have successfully implemented explicit animations using Core Animation classes outside of a UIView animation block.

Have I misunderstood this passage, or is it out-of-date, or something else?


Some additional notes:

I assume that "the UIView class disables layer animations by default but reenables them inside animation blocks" refers to the +[UIView setAnimationsEnabled:] method. When I get back to a computer that can do so, I'll check to see whether +[UIView areAnimationsEnabled] returns YES or NO.

回答1:

That quote refers to the layer that is backing the view. It is not true for stand-alone layers that you create and manage yourself.


Every view on iOS is backed by a layer. When you change the view's properties, it changes the underlying layer property. By default the layer would have implicit animations, but the layer "disables" that behavior except for when you are inside of an UIView animation block. This is what that part of the documentation is referring to.

There are a couple of ways you can use Core Animation to animate a layer property. The most common is to add the animation object to the layer when you want to animate the property, but you can also make customizations through the actions dictionary and the styles dictionary if you always want to animate when a property changes. The last two would also be disabled for the layer that is backing a view.