Note that there are some explanatory texts on larger screens.

plurals
  1. POHow exactly to subclass CALayer and use a custom property?
    text
    copied!<p>I am trying to create a subclass of <code>CALayer</code> with a custom <code>index</code> property that I can both animate and change directly in order to display a different picture based on the index.</p> <p>In the header, I declared:</p> <pre><code>@property NSUInteger index; </code></pre> <p>In the implementation, I overrode <code>needDisplayForKey</code>:</p> <pre><code>+ (BOOL)needsDisplayForKey:(NSString *)key { if ([key isEqualToString:@"index"]) return YES; else return [super needsDisplayForKey:key]; } </code></pre> <p>Now, in the <code>display</code> method, I want to display a picture based on the index. However, during an animation, the value of <code>self.index</code> never changes, so I have to query the value of the presentation layer, contrary to the example on <a href="https://developer.apple.com/library/mac/#documentation/cocoa/conceptual/coreanimation_guide/Articles/ProvidingCALayerContent.html#//apple_ref/doc/uid/TP40006642-SW1" rel="noreferrer">Providing CALayer Content by Subclassing</a>:</p> <pre><code>- (void)display { NSUInteger presentationIndex = [(CustomLayer *)[self presentationLayer] index]; self.contents = (id)[[images objectAtIndex:presentationIndex] CGImage]; } </code></pre> <p>The problem is, if I do that, I cannot set the <code>index</code> value directly outside of an animation, because it will only change the model layer, and the <code>display</code> method explicitly queries the presentation layer.</p> <p>If I add an initialization method that copies the value of <code>index</code>, it works:</p> <pre><code>- (id)initWithLayer:(id)layer { self = [super initWithLayer:layer]; if (self) { if ([layer isKindOfClass:[CustomLayer class]]) self.index = [(CustomLayer *)layer index]; } return self; } </code></pre> <p>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 <code>index</code> to the destination value or not).</p> <ul> <li>Surprisingly, it seems like the <code>drawInContext:</code> method always has the right value for <code>[self index]</code>, but it is not the method I want to use since I just set the <code>content</code> property with an image.</li> <li>I get different behaviors depending on the way I implement the <code>index</code> property. If I use <code>@dynamic index</code> (which works, even though the documentation doesn't say that custom property getters/setters would be dynamically implemented), <code>display</code> is called every time the value of <code>index</code> is changed. If I use <code>@synthesize</code> or implement a setter, <code>display</code> is not called, so I would need to change <code>content</code> in the setter too.</li> <li>Should I use an instance variable? Should I use the dynamic implementation? Or should I use <code>setValue:forKey:</code> instead?</li> </ul> <p>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!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload