使用actionForKey的自定义属性动画:如何获取属性的新值?

Eya*_*ler 7 core-animation

在我正在研究的CALayer子类中,我有一个我想自动动画的自定义属性,也就是说,假设该属性被称为"myProperty",我想要以下代码:

[myLayer setMyProperty:newValue];
Run Code Online (Sandbox Code Playgroud)

使得当前值的平滑动画变为"newValue".

使用覆盖actionForKey:和needsDisplayForKey的方法:(参见下面的代码)我能够非常好地运行它来简单地在旧值和新值之间进行插值.

我的问题是我想使用稍微不同的动画持续时间或路径(或其他),具体取决于属性的当前值和新值,我无法弄清楚如何从actionForKey中获取新值:

提前致谢

@interface ERAnimatablePropertyLayer : CALayer {
    float myProperty;
}
@property (nonatomic, assign) float myProperty;
@end
@implementation ERAnimatablePropertyLayer
@dynamic myProperty;

- (void)drawInContext:(CGContextRef)ctx {
     ... some custom drawing code based on "myProperty"
}

- (id <CAAction>)actionForKey:(NSString *)key {
    if ([key isEqualToString:@"myProperty"]) {
        CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:key];
        theAnimation.fromValue = [[self presentationLayer] valueForKey:key];

        ... I want to do something special here, depending on both from and to values...


        return theAnimation;
        }
    return [super actionForKey:key];
    }

+ (BOOL)needsDisplayForKey:(NSString *)key {
    if ([key isEqualToString:@"myProperty"])
        return YES;
    return [super needsDisplayForKey:key];
    }
    @end
Run Code Online (Sandbox Code Playgroud)

Sim*_*mon 1

您可以将旧值和新值存储在 CATransaction 中。

-(void)setMyProperty:(float)value
{
    NSNumber *fromValue = [NSNumber numberWithFloat:myProperty];
    [CATransaction setValue:fromValue forKey:@"myPropertyFromValue"];

    myProperty = value;

    NSNumber *toValue = [NSNumber numberWithFloat:myProperty];
    [CATransaction setValue:toValue forKey:@"myPropertyToValue"];
}

- (id <CAAction>)actionForKey:(NSString *)key {
    if ([key isEqualToString:@"myProperty"]) {
        CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:key];
        theAnimation.fromValue = [[self presentationLayer] valueForKey:key];
        theAnimation.toValue = [CATransaction objectForKey:@"myPropertyToValue"];

        // here you do something special.
    }

    return [super actionForKey:key];
}
Run Code Online (Sandbox Code Playgroud)