如何完成子类CALayer并使用自定义属性? [英] How exactly to subclass CALayer and use a custom property?

查看:151
本文介绍了如何完成子类CALayer并使用自定义属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用自定义索引属性创建 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 the content 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 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.
  • 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:

使用自定义CALayer动画饼图片

看起来主要技巧是:

使用@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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆