我有一个 CALayer 子类 MyLayer,它有一个名为 myInt 的 NSInteger 属性。我真的很想通过 CABasicAnimation 为这个属性设置动画,但似乎 CABasicAnimation 只适用于所谓的“动画”属性(边界、位置等)。有什么我可以覆盖的东西来使我的自定义 myInt 属性可动画化吗?
问问题
11394 次
3 回答
69
是的,这是可能的(不过,我相信只有在最新的 Core Animation 版本中,即 iPhone 3.0+ 和 OS X 10.6+)。
使您的属性动态化,以便 CA 为您实现访问器:
@dynamic myInt;
告诉图层属性的变化需要重绘:
+ (BOOL)needsDisplayForKey:(NSString*)key { if ([key isEqualToString:@"myInt"]) { return YES; } else { return [super needsDisplayForKey:key]; } }
myInt
在您的drawInContext:
方法中使用 的值。现在,当您制作动画时myInt
,Core Animation 将为动画的每一步插入值,并反复要求图层自行绘制。如果您还想为此属性启用隐式动画,请同时覆盖
actionForKey:
。
于 2010-03-07T13:53:08.753 回答
6
有一种方法可以保留自定义 CALayer 子类的 iVar。您覆盖 initWithLayer:,该方法被调用以创建自定义图层的副本。例如,如果您有一个图层,要在其中创建一个名为“角度”的自定义属性,则可以使用以下代码:
@implementation AngledLayer
@synthesize angle = _angle
// Tell Core Animation that this key should be animated
+ (BOOL) needsDisplayForKey:(NSString *)key
{
if ([key isEqualToString:@"angle"]) return YES;
return [super needsDisplayForKey:key];
}
// Make sure that, when the layer is copied, so is the custom ivar
- (id) initWithLayer:(id)layer
{
self = [super initWithLayer:layer];
if (self) {
AngledLayer *angledVersion = (AngledLayer *)layer;
self.angle = angledVersion.angle;
}
return self;
}
鲍勃是你的叔叔!请注意,您不能将此对象与隐式动画一起使用,为此您还必须覆盖 actionForKey: 方法。
于 2012-03-09T20:44:47.773 回答
0
斯威夫特版本
// Custom property
@NSManaged public var progress: CGFloat
open override class func needsDisplay(forKey key: String) -> Bool {
if key == "progress" {
return true
}
return super.needsDisplay(forKey: key)
}
于 2021-05-30T21:38:31.237 回答