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).
- Surprisingly, it seems like the
drawInContext:
method always has the right value for[self index]
, but it is not the method I want to use since I just set thecontent
property with an image. - I get different behaviors depending on the way I implement the
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 ofindex
is changed. If I use@synthesize
or implement a setter,display
is not called, so I would need to changecontent
in the setter too. - Should I use an instance variable? Should I use the dynamic implementation? Or should I use
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!