I am trying to create a subclass of CALayer
with a custom index
property that I can both animate and change directly in order to display a different picture based on the index.
In the header, I declared:
@property NSUInteger index;
In the implementation, I overrode needDisplayForKey
:
+ (BOOL)needsDisplayForKey:(NSString *)key
{
if ([key isEqualToString:@"index"])
return YES;
else
return [super needsDisplayForKey:key];
}
Now, in the display
method, I want to display a picture based on the index. However, during an animation, the value of self.index
never changes, so I have to query the value of the presentation layer, contrary to the example on Providing CALayer Content by Subclassing:
- (void)display
{
NSUInteger presentationIndex = [(CustomLayer *)[self presentationLayer] index];
self.contents = (id)[[images objectAtIndex:presentationIndex] CGImage];
}
The problem is, if I do that, I cannot set the index
value directly outside of an animation, because it will only change the model layer, and the display
method explicitly queries the presentation layer.
If I add an initialization method that copies the value of index
, it works:
- (id)initWithLayer:(id)layer
{
self = [super initWithLayer:layer];
if (self) {
if ([layer isKindOfClass:[CustomLayer class]])
self.index = [(CustomLayer *)layer index];
}
return self;
}
However, after or before an animation, there is always a 1 image glitch because the presentation or the model value don't match (depending if I set index
to the destination value or not).
drawInContext:
method always has
the right value for [self index]
, but it is not the method I want to use since I just set the content
property with an image.index
property. If I use @dynamic index
(which works, even though the documentation doesn't say that custom property getters/setters would be dynamically implemented), display
is called every time the value of index
is changed. If I use @synthesize
or implement a setter, display
is not called, so I would need to change content
in the setter too.setValue:forKey:
instead?As you can see, I am a bit confused about how to get the result I want, and how to correctly implement a subclass of CALayer with a custom property. Any help, and explanations, would be appreciated!
There is an excellent tutorial on the web that explains how to create a custom CALayer subclass with animatable properties. I haven't had occasion to try it yet, but I bookmarked it. Here is the link:
Animating Pie Slices Using a Custom CALayer
It looks like the main tricks are:
Use @dynamic, not @synthesize for the animatable properties of your custom CALayer.
Override actionForKey:, initWithLayer:, and needsDisplayForKey:, and perhaps drawInContext:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With