CALayer子类的属性不会被CATransaction观察到 [英] Properties on CALayer subclass aren't getting observed by 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屋!