Graphics Reference
In-Depth Information
If you run the project, you'll notice that the color snaps to its new value immediately when
the button is pressed instead of animating smoothly as before. What's going on? The
implicit animation seems to have been disabled for the UIView backing layer.
Come to think of it, we'd probably have noticed if UIView properties always animated
automatically whenever we modified them. So, if UIKit is built on top of Core Animation
(which always animates everything by default), how come implict animations are disabled
by default in UIKit?
We know that Core Animation normally animates any property change of a CALayer
(provided it can be animated) and that UIView somehow turns this behavior off for its
backing layer. To understand how it does that, we need to understand how implicit
animations are implemented in the first place.
The animations that CALayer automatically applies when properties are changed are
called actions. When a property of a CALayer is modified, it calls its -actionForKey:
method, passing the name of the property in question. What happens next is quite nicely
documented in the header file for CALayer , but it essentially boils down to this:
1.
The layer first checks whether it has a delegate and if the delegate implements the
-actionForLayer:forKey method specified in the CALayerDelegate
protocol. If it does, it will call it and return the result.
2.
If there is no delegate, or the delegate does not implement
-actionForLayer:forKey , the layer checks in its actions dictionary,
which contains a mapping of property names to actions.
3.
If the actions dictionary does not contain an entry for the property in question,
the layer searches inside its style dictionary hierarchy for any actions that match
the property name.
4.
Finally, if it fails to find a suitable action anywhere in the style hierarchy, the
layer will fall back to calling the -defaultActionForKey: method, which
defines standard actions for known properties.
The result of this exhaustive search will be that -actionForKey: either returns nil (in
which case, no animation will take place and the property value will change immediately)
or an object that conforms to the CAAction protocol, which CALayer will then use to
animate between the previous and current property values.
And that explains how UIKit disables implicit animations: Every UIView acts as the
delegate for its backing layer and provides an implementation for the
-actionForLayer:forKey method. When not inside an animation block, UIView
returns nil for all layer actions, but within the scope of an animation block it returns non-
nil values. We can demonstrate this with a simple experiment (see Listing 7.5).
Listing 7.5 Testing UIView's actionForLayer:forKey: Implementation
@interface ViewController ()
Search WWH ::




Custom Search