Search code examples
ioscore-animation

Why doesn't the following Core Animation implicit animation work?


The code below is a subclass of CALayer. If I call animateVal, the drawInContext is animated. That's great.

I tried to turn that into an implicit animation with actionForKey. If I assign a value to the val property (layer.val = 10), val is changed immediately and drawInContext is repeatedly called with the same value of val, the one I just assigned, over and over.

What am I doing wrong?

@interface MyLayer : CALayer
@property (nonatomic, assign) CGFloat val;
- (void)animateVal:(CGFloat)val;
@end

@implementation MyLayer
@dynamic val;

+ (BOOL)needsDisplayForKey:(NSString *)key {
    return [key isEqualToString:@"val"] || [super needsDisplayForKey:key];
}

- (id<CAAction>)actionForKey:(NSString *)event {
    if ([event isEqualToString:@"val"]) {
        CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"val"];
        anim.duration = 3.0;
        return anim;
    }

    return [super actionForKey:event];
}

- (void)animateVal:(CGFloat)val {
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"val"];
    anim.toValue = [NSNumber numberWithFloat:val];
    anim.duration = 3.0;
    [self addAnimation:anim forKey:nil];
}

- (void)drawInContext:(CGContextRef)ctx {

    CGContextAddRect(ctx, CGRectMake(10, 10, self.val, self.val));
    CGContextSetFillColorWithColor(ctx, [UIColor greenColor].CGColor);
    CGContextFillPath(ctx);
}

@end

Solution

  • Argh.

    The solution is to set the fromValue when returning the action.

        anim.fromValue = [[self presentationLayer] valueForKey:event];