Out of the box, CALayer supports many animatable properties where a change will automatically create a CAAnimation for that property. But, if you look at the list of properties, it is clear that they are all of the form “stuff that OpenGL does while compositing” and have nothing to do with the inner texture representing your content. You are entirely responsible for telling CoreAnimation when your content has changed.
Recently I wanted to write a layer that had its content animate, but as far as I could determine CALayer doesn't support this out of the box, though it is really pretty close. If you add an @dynamic property to a CALayer subclass and set it, your layer will be sent -actionForKey: and the returned animation will be passed to your -addAnimation:forKey:.
The problem is that CALayer doesn't know that this change means it needs to update your contents property too, so the animation will happen but no display change will happen.
The API on CALayer really isn't sufficient for this task, so it isn't too surprising it isn't supported. Since CALayer is a generic KVC container you can squirrel away random keys/value pairs in it and use them for whatever purposes you want. But it has no way of knowing that a particular property change should provoke an update to the content, and updating the content unnecessarily would seriously hurt performance.
I've whipped up some sample code with a superclass that shows one approach to handling this.
The sample subclass looks like:
@interface WaveLayer : ContentAnimatingLayer@property CGFloat phase, frequency, amplitude;
@end
@implementation WaveLayer
@dynamic phase, frequency, amplitude;
+ (NSSet *)keyPathsForValuesAffectingContent;
{
static NSSet *keys = nil;
if (!keys)
keys = [[NSSet alloc] initWithObjects:@"phase",
@"frequency", @"amplitude", nil];
return keys;
}
- (void)drawInContext:(CGContextRef)ctx;
{
… draw a sine wave …
}
@end
The ContentAnimatingLayer superclass provides some bookkeeping and basic support for updating the content when the content-affecting properties are changed. First, it adds support for -actionFor
This makes it as easy as I'd hoped it would be to write content animating layers; hopefully you'll find this useful too! I've asked Apple to add this to CALayer in the future. If you'd like it too, you can reference my Radar #6372372.
The sample code is just that, my first cut at a sample. Some possible issues/improvements:
-
-
Commenting is not available in this section entry.twobyte
11.14.08 9:16 AM
Tim
11.17.08 4:03 AM