问题描述
我有一个 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 $ c进行更改$ c>通过调用
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
的示例,用于动画自定义属性(取自。完整的可在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子类的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!