动画化CALayer子类的自定义属性

jem*_*ons 30 iphone core-animation calayer

我有一个CALayer子类MyLayer,它有一个名为myInt的NSInteger属性.我真的想通过CABasicAnimation为这个属性设置动画,但似乎CABasicAnimation只适用于所谓的"动画"属性(边界,位置等).有什么我可以覆盖,以使我的自定义myInt属性可动画?

Ole*_*ann 69

是的,这是可能的(但我认为,仅在最新的Core Animation版本中,即iPhone 3.0+和OS X 10.6+).

  1. 使您的属性动态化,以便CA为您实现访问者:

    @dynamic myInt;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 告诉图层属性的更改需要重绘:

    + (BOOL)needsDisplayForKey:(NSString*)key {
        if ([key isEqualToString:@"myInt"]) {
            return YES;
        } else {
            return [super needsDisplayForKey:key];
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用的价值myInt在你的drawInContext:方法.现在,当您进行动画处理时myInt,Core Animation将为动画的每个步骤插值,并反复要求图层绘制自己.

  4. 如果您还想为此属性启用隐式动画,请同时覆盖actionForKey:.

  • 亲爱的未来googlers:CGContextDrawImage()没有绘图,因为我将它的CGImageRef存储在一个ivar中.当CoreAnimation产生多个表示层(或其他)时,它不会复制ivars,只会复制KVC值.将我的图像存储在UIImage中然后[self setValue:myUIImage forKey:@"image"]以便以后在-drawInContext中检索:做了诀窍. (9认同)
  • 没关系.你的回复仍然是我在Stack Overflow上看到的最好的书面答案之一:) (3认同)

小智 6

这里是一个办法留住您的自定义CALayer的子类的实例变量.您覆盖initWithLayer:,该方法被调用以创建自定义图层的副本.例如,如果您有一个图层要在其中创建名为"angle"的自定义属性,则可以使用以下代码:

@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;
}
Run Code Online (Sandbox Code Playgroud)

鲍勃是你的叔叔!请注意,您不能将此对象与隐式动画一起使用,您还必须覆盖actionForKey:方法.