如何继承CALayer并使用自定义属性?

时间:2012-04-30 16:49:23

标签: iphone core-animation calayer

我正在尝试使用自定义CALayer属性创建index的子类,我可以直接设置动画和更改,以便根据索引显示不同的图片。

在标题中,我声明:

@property NSUInteger index;

在实施中,我覆盖了needDisplayForKey

+ (BOOL)needsDisplayForKey:(NSString *)key
{
    if ([key isEqualToString:@"index"])
        return YES;
    else
        return [super needsDisplayForKey:key];
}

现在,在display方法中,我想根据索引显示图片。但是,在动画期间,self.index的值永远不会改变,所以我必须查询表示层的值,这与Providing CALayer Content by Subclassing上的示例相反:

- (void)display
{
    NSUInteger presentationIndex = [(CustomLayer *)[self presentationLayer] index];
    self.contents = (id)[[images objectAtIndex:presentationIndex] CGImage];
}

问题是,如果我这样做,我不能直接在动画之外设置index值,因为它只会更改模型层,而display方法会显式查询表示层

如果我添加一个复制index值的初始化方法,它可以工作:

- (id)initWithLayer:(id)layer
{
    self = [super initWithLayer:layer];
    if (self) {
        if ([layer isKindOfClass:[CustomLayer class]])
            self.index = [(CustomLayer *)layer index];
    }
    return self;
}

但是,在动画之前或之后,始终存在1个图像毛刺,因为演示文稿或模型值不匹配(取决于我是否将index设置为目标值。)

  • 令人惊讶的是,似乎drawInContext:方法总是如此 [self index]的正确值,但它不是我想要使用的方法,因为我只是将content属性设置为图像。
  • 根据我实现index属性的方式,我会得到不同的行为。如果我使用@dynamic index(即使文档没有说动态实现自定义属性getter / setter),每次display的值为index时都会调用@synthesize改变。如果我使用display或实施设置器,则不会调用content,因此我还需要在设置器中更改setValue:forKey:
  • 我应该使用实例变量吗?我应该使用动态实现吗?或者我应该使用{{1}}代替吗?

正如您所看到的,我对如何获得我想要的结果以及如何使用自定义属性正确实现CALayer的子类感到困惑。任何帮助和解释,将不胜感激!

1 个答案:

答案 0 :(得分:11)

网上有一个很好的教程,解释了如何创建具有可动画属性的自定义CALayer子类。我没有机会尝试它,但我给它添加了书签。这是链接:

Animating Pie Slices Using a Custom CALayer

看起来主要的伎俩是:

使用@dynamic而非@synthesize获取自定义CALayer的可动画属性。

覆盖actionForKey:,initWithLayer:和needsDisplayForKey:,也许是drawInContext: