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

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

问题描述

我有一个带有自定义属性的 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:方法的委托,该方法返回动画,但是无论如何在[code] [CATransaction开始] ... [CATransaction结束] 内对 someMyLayerInstance.customValue 进行的更改不会导致 actionForLayer:forKey 被调用相应的键"值.

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 上设置属性,并通过调用 setValue:forKey: 做到来对 myLayerInstance 进行更改导致 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?

推荐答案

最重要的是,您需要使用 @dynamic 实现所有 CALayer 访问器.不要使用 @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编程突破极限的第7章,.完整的示例代码可在Wiley网站上找到.)层,但是您仍然可以根据需要在委托中实现该部分.

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

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

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