Iphone 为什么设置自定义CALayer特性的动画会导致其他特性在动画期间为零?

Iphone 为什么设置自定义CALayer特性的动画会导致其他特性在动画期间为零?,iphone,animation,properties,calayer,null,Iphone,Animation,Properties,Calayer,Null,我有一个自定义CALayer(比如CircleLayer),包含自定义属性(半径和色调)。层在其drawInContext:方法中呈现自身 - (void)drawInContext:(CGContextRef)ctx { NSLog(@"Drawing layer, tint is %@, radius is %@", self.tint, self.radius); CGPoint centerPoint = CGPointMake(CGRectGetWidth(self.

我有一个自定义CALayer(比如CircleLayer),包含自定义属性(半径和色调)。层在其drawInContext:方法中呈现自身

- (void)drawInContext:(CGContextRef)ctx {
    NSLog(@"Drawing layer, tint is %@, radius is %@", self.tint, self.radius);

    CGPoint centerPoint = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);

    CGContextMoveToPoint(ctx, centerPoint.x, centerPoint.y);
    CGContextAddArc(ctx, centerPoint.x, centerPoint.y, [self.radius doubleValue], radians(0), radians(360), 0);
    CGContextClosePath(ctx);

    /* Filling it */
    CGContextSetFillColorWithColor(ctx, self.tint.CGColor);
    CGContextFillPath(ctx); 
}
我希望半径可以设置动画,所以我已经实现了

+ (BOOL)needsDisplayForKey:(NSString *)key {
    if ([key isEqualToString:@"radius"]) {
        return YES;
    }
    return [super needsDisplayForKey:key];
}
动画的执行方式如下:

CABasicAnimation *theAnimation=[CABasicAnimation animationWithKeyPath:@"radius"];
theAnimation.duration=2.0;
theAnimation.fromValue=[NSNumber numberWithDouble:100.0];
theAnimation.toValue=[NSNumber numberWithDouble:50.0];
theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

[circleLayer addAnimation:theAnimation forKey:@"animateRadius"];

circleLayer.radius = [NSNumber numberWithDouble:50.0];
drawInContext:在动画过程中按预期调用以重新绘制圆,但动画一开始,着色就设置为零,动画结束时,着色就恢复到其原始值

我的结论是,如果我想为自定义属性设置动画,并希望其他属性在动画期间保持其值,我也必须为它们设置动画,我发现这一点都不方便

其目的不是增加/缩小一个圆,我知道我可以使用变换来实现这一点。仅用一个简单的示例来说明设置单个自定义特性的动画而不必设置所有其他特性的动画的问题

我做了一个简单的项目来说明这个问题,你可以在这里找到:

可能有些东西我没有弄清楚CoreAnimation是如何工作的,我已经进行了深入的搜索,但我没有任何线索。有人知道吗

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

动画可能需要上下文的所有属性来响应刷新。

如果我正确理解了您的问题,它是这样的。将动画添加到CALayer时,它将使用
initWithLayer:
创建该层的所谓表示副本。表示层包含每个动画帧的实际动画状态,而原始层具有最终状态。为自己的属性设置动画的问题是,CALayer不会在
initWithLayer:
中复制所有属性。如果是这样,您应该覆盖
initWithLayer:
并设置动画所需的所有属性,即色调和半径。

这非常有用。它救了我一天。