Another CoreAnimation Gotcha

As I said before, the documentation available for CoreAnimation is a bit lacking.  This one had me scratching my head for a time today.

For my current project, I have several layers that should have some of their default animation actions disabled.  This is pretty easy to do by handing a dictionary with the desired keys set to an instance of NSNull.  For example:

NSDictionary *actions = [NSDictionary dictionaryWithObjectsAndKeys:[NSNull null], @"position", nil];

CALayer *aLayer = [[CALayer alloc] init];

aLayer.actions = actions;

Under a different set of circumstances I need to reenable the animation.  This, too, is simple to do using CABasicAnimation:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];

animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

[aLayer addAnimation:animation forKey:@"position"];

This code runs fine, until you have the need to intercept the animation while it’s executing.  A CALayer maintains two versions of itself.

The first is the model layer ([aLayer modelLayer]), which gets written to when you change a property on it.  For example, setting the position to {10, 10} writes this information to the model layer, and is present throughout the animation.

The second is the presentation layer ([aLayer presentationLayer]), which hold the location of the CALayer as it’s presented on the screen.  If you want to interact with the layer as it’s moving, you need to access this layer.  If you’re using the default actions on the layer, this all works as expected.  Once you replace the default action, there’s another step you have to take which is not clearly stated in the documentation:

animation.fromValue = [NSValue valueWithCGPoint:start];
animation.toValue = [NSValue valueWithCGPoint:end];

Without specifying a start and end point, the action is unable to interpolate intermediate values during the animation.  If you inspect the presentation layer without specifying a start and end, you’ll find that the values for the property you’re looking for are the same as those in the model layer.


Posted on February 24, 2011, in Code and tagged , , . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: