16

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

在标题中,我声明:

@property NSUInteger index;

在实现中,我覆盖了needDisplayForKey

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

现在,在display方法中,我想根据索引显示一张图片。但是,在动画期间,值self.index永远不会改变,所以我必须查询表示层的值,这与通过子类化提供 CALayer 内容的示例相反:

- (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或实现 setter,display则不会调用,所以我也需要更改contentsetter。
  • 我应该使用实例变量吗?我应该使用动态实现吗?还是我应该setValue:forKey:改用?

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

4

1 回答 1

11

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

使用自定义 CALayer 动画饼片

看起来主要技巧是:

对自定义 CALayer 的动画属性使用 @dynamic,而不是 @synthesize。

覆盖 actionForKey:、initWithLayer: 和 needsDisplayForKey:,也许还有 drawInContext:

于 2012-07-08T01:21:31.027 回答