如何完成子类CALayer并使用自定义属性? [英] How exactly to subclass CALayer and use a custom property?
问题描述
我正在尝试使用自定义索引
属性创建 CALayer
的子类,我可以设置其动画和更改直接为了根据索引显示不同的图片。
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.
在标题中,我声明:
@property NSUInteger index;
在实施中,我覆盖 needDisplayForKey
:
+ (BOOL)needsDisplayForKey:(NSString *)key
{
if ([key isEqualToString:@"index"])
return YES;
else
return [super needsDisplayForKey:key];
}
现在,在显示
方法,我想根据索引显示图片。但是,在动画期间, self.index
的值永远不会改变,所以我必须查询表示层的值,这与提供CALayer内容通过子类化:
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];
}
问题是,如果我这样做,我就不能设置 index
直接在动画之外的值,因为它只会更改模型层,而 display
方法会显式查询表示层。
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.
如果我添加一个复制 index
值的初始化方法,它可以工作:
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;
}
然而,在动画之前或之后,总会出现1个图像故障,因为演示文稿或模型值不匹配(取决于我是否将 index
设置为目标值)。
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:
方法总是有
的正确值[self index ]
,但这不是我想要使用的方法,因为我只是用图像设置content
属性。 - 根据我实现
index
属性的方式,我会得到不同的行为。如果我使用@dynamic index
(即使文档没有说动态实现自定义属性getter / setter),显示每次更改
。如果我使用index
的值时,都会调用@synthesize
或实现一个setter,则不会调用display
,所以我需要更改<$ c在setter中也是$ c> content 。 - 我应该使用实例变量吗?我应该使用动态实现吗?或者我应该使用
setValue:forKey:
而不是?
- 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?
正如你所看到的,我对如何获得我想要的结果以及如何使用自定义属性正确实现CALayer的子类感到困惑。任何帮助和解释,将不胜感激!
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!
推荐答案
网上有一个很好的教程,解释了如何创建自定义具有可动画属性的CALayer子类。我没有机会尝试它,但我给它添加了书签。这是链接:
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:
看起来主要技巧是:
使用@dynamic,而不是@synthesize来获取自定义CALayer的可动画属性。
Use @dynamic, not @synthesize for the animatable properties of your custom CALayer.
覆盖actionForKey:,initWithLayer:和needsDisplayForKey:,也许还有drawInContext:
Override actionForKey:, initWithLayer:, and needsDisplayForKey:, and perhaps drawInContext:
这篇关于如何完成子类CALayer并使用自定义属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!