CATransaction没有观察到CALayer子类的属性 [英] Properties on CALayer subclass aren't getting observed by CATransaction

查看:90
本文介绍了CATransaction没有观察到CALayer子类的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a subclass of CALayer with a custom property, declared as such:

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

我想在显式 CATranasction ,所以我设置了一个代理,其中实现了 actionForLayer:forKey:方法,该方法返回动画,但对<$ c $的任何更改c> someMyLayerInstance.customValue 在 [CATransaction begin] ... [CATransaction end] 内部不会导致 actionForLayer: forKey 使用相应的key值调用。

I want to animate this property inside of an explicit CATranasction, so i set up a delegate with the actionForLayer:forKey: method implemented which returns an animation, however any changes to someMyLayerInstance.customValue inside of [CATransaction begin] ... [CATransaction end] do not result in actionForLayer:forKey getting called with a corresponding 'key' value.

然而,在 MyLayer 上查看该属性并对 myLayerInstance 通过调用 setValue:forKey: 确实导致 actionForLayer:forKey:获取调用。

However, nuking the property on MyLayer and making changes to myLayerInstance by calling setValue:forKey: does result in actionForLayer:forKey: getting called.

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

It appears that this is because CALayer does some mojo for key/value coding for undefined properties. How can I recreate this mojo so that I can declare properties on MyLayer, but still have them be observed by the animation delegate?

推荐答案

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

The most important thing is that you need to implement all CALayer accessors using @dynamic. Do not use @synthesize and do not implement the accessors directly. CALayer generates all its own property handlers (as you've indirectly discovered), and you need to let those be used.

您还需要让 CALayer 知道此属性是影响显示的(您可能已经根据其他评论已经完成)。如果还没有,可以通过实现 + needsDisplayForKey:并为您的密钥返回 YES 来实现。

You also need to let CALayer know that this property is display-impacting (which you may have already done given your other comments). If you haven't, you do this by implementing +needsDisplayForKey: and returning YES for your key.

这是一个 CALayer 的示例,用于动画自定义属性(取自iOS 5编程推动极限。完整的示例代码可在Wiley网站。)这个例子在图层中实现 actionForKey:,但如果你愿意,你仍然可以在委托中实现该部分。

Here's an example of a CALayer that animates a custom property (taken from Chapter 7 of iOS 5 Programming Pushing the Limits. The full sample code is available at the Wiley site.) This example implements actionForKey: in the layer, but you can still implement that part in the delegate if you prefer.

@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

这篇关于CATransaction没有观察到CALayer子类的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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