CATransaction 未观察到 CALayer 子类上的属性



我有一个CALayer的子类,它有一个自定义属性,声明如下:

@interface MyLayer : CALayer
    @property (nonatomic,retain) NSNumber *customValue;
@end
@implementation MyLayer
    @synthesize customValue = _customValue;
@end

我想在显式CATranasction中设置此属性的动画,所以我使用实现的actionForLayer:forKey:方法设置了一个委托,该方法返回动画,但是在[CATransaction begin] ... [CATransaction end]中对someMyLayerInstance.customValue的任何更改都不会导致actionForLayer:forKey被调用相应的"key"值。

但是,通过调用setValue:forKey:MyLayer上的属性进行核处理并更改myLayerInstance会导致调用actionForLayer:forKey:

这似乎是因为CALayer为未定义属性的键/值编码做了一些技巧。我如何重新创建这个魔力,以便在MyLayer上声明属性,但仍然让动画代理观察它们?

最重要的是,您需要使用@dynamic实现所有CALayer访问器。不要使用@synthesize,也不要直接实现访问器。CALayer生成它自己的所有属性处理程序(正如您间接发现的那样),您需要使用这些处理程序。

您还需要让CALayer知道此属性会影响显示(您可能已经在给出其他注释的情况下这样做了)。如果您还没有,您可以通过实现+needsDisplayForKey:并返回密钥的YES来完成此操作。

以下是一个为自定义属性设置动画的CALayer示例(取自iOS 5编程突破极限的第7章。完整的示例代码可在Wiley网站上获得。)此示例在层中实现actionForKey:,但如果您愿意,您仍然可以在委托中实现该部分。

@implementation CircleLayer
@dynamic radius;
...
+ (BOOL)needsDisplayForKey:(NSString *)key {
  if ([key isEqualToString:@"radius"]) {
    return YES;
  }
  return [super needsDisplayForKey:key];
}
- (id < CAAction >)actionForKey:(NSString *)key {
  if ([self presentationLayer] != nil) {
    if ([key isEqualToString:@"radius"]) {
      CABasicAnimation *anim = [CABasicAnimation
                                animationWithKeyPath:@"radius"];
      anim.fromValue = [[self presentationLayer] 
                        valueForKey:@"radius"];
      return anim;
    }
  }
  return [super actionForKey:key];
}
@end

最新更新