Graphics Reference
In-Depth Information
Taking that into account, if we insert the following two lines between where we create our
animation and where we add it to the layer, it should get rid of the snap-back:
animation.fromValue = ( __bridge id ) self . colorLayer .backgroundColor;
self . colorLayer .backgroundColor = color.CGColor;
That works, but is potentially unreliable. We should really derive the fromValue from the
presentation layer (if it exists) rather than the model layer, in case there is already an
animation in progress. Also, because the layer in this case is not a backing layer, we should
disable implicit animations using a CATransaction before setting the property, or the
default layer action may interfere with our explicit animation. (In practice, the explicit
animation always seems to override the implicit one, but this behavior is not documented,
so it's better to be safe than sorry.)
If we make those changes, we end up with the following:
CALayer *layer = self . colorLayer . presentationLayer ?: self . colorLayer;
animation. fromValue = ( __bridge id )layer. backgroundColor ;
[ CATransaction begin ];
[ CATransaction setDisableActions : YES ];
self . colorLayer . backgroundColor = color. CGColor ;
[ CATransaction commit ];
That's quite a lot of code to have to add to each and every animation. Fortunately, we can
derive this information automatically from the CABasicAnimation object itself, so we can
create a reusable method. Listing 8.2 shows a modified version of our first example that
includes a method for applying a CABasicAnimation without needing to repeat this
boilerplate code each time.
Listing 8.2 A Reusable Method for Fixing Animation Snap-Back
- ( void )applyBasicAnimation:( CABasicAnimation *)animation
toLayer:( CALayer *)layer
{
//set the from value (using presentation layer if available)
animation. fromValue = [layer. presentationLayer ?: layer
valueForKeyPath :animation. keyPath ];
//update the property in advance
//note: this approach will only work if toValue != nil
[ CATransaction begin ];
[ CATransaction setDisableActions : YES ];
[layer setValue :animation. toValue forKeyPath :animation. keyPath ];
[ CATransaction commit ];
//apply animation to layer
[layer addAnimation :animation forKey : nil ];
}
Search WWH ::




Custom Search