secondary 属性 动画后更新不卡住

secondary property update not sticking after animation

此处为 REPRO 存储库:https://github.com/kaolin/38492498/tree/master


我有一个@property int percentScanned.

我已经设置了 needsDisplayForKey:

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

我的展示方式:

- (void)display {
    _percentTextLayer.string = [NSString stringWithFormat:@"%02d%%",[[self presentationLayer] percentScanned]];
}

我的动画:

    [CATransaction begin];
    self.percentScanned = 99;
    _percentTextLayer.string=@"99%";
    [CATransaction setCompletionBlock:^{
        _percentTextLayer.string=@"99%";
        self.percentScanned = 99;
    }];
    {
        CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@"percentScanned"];
        [a setFromValue:@0];
        [a setToValue:@99];
        [a setDuration:4.];
        [self addAnimation:a forKey:@"percentage"];
    }
    [CATransaction commit];

一切正常,除了在动画结束时,我的模型层字符串返回到“00%”。如您所见,我已经把感觉像是厨房水槽的东西扔掉了,迫使它保持在“99%”(在 animation.removedOnCompletion = NO;animation.fillMode = kCAFillModeForwards; 的 "hack" 之外——实际上,添加那些没有帮助!)。

大约 3/30 秒后在同一层上有另一个动画,淡化不透明度....但是将其推出或删除它不会'似乎有所作为。

我知道如何为标准动画值执行此操作,但我缺少有关如何使用这样的 secondary/evaluated 值执行此操作的内容....


编辑添加:

一路走来,添加 animation.removedOnCompletion = NO;animation.fillMode = kCAFillModeForwards; 确实开始了 "working",但我不想泄露动画....

如果我为 percentScanned 添加一个 setter,它不会在最后用 0 调用,但会在最后用 0 调用显示。很难追踪调用 setPercentScanned 和调用显示之间的 link...

我可以破解我的 display 阅读如下:

- (void)display {
    if ([[self presentationLayer] percentScanned] != 0) {
        _percentTextLayer.string = [NSString stringWithFormat:@"%02d%%",[[self presentationLayer] percentScanned]];
    }
}

然后它适用于我的特定用例,但这仍然不理想....

并且在 display 方法中放置一个断点是相当无益的(当然它只是发生在 display_if_needed 内部)。 :/

基本上,将最终值直接设置到图层上并仅对 fromValue 进行动画处理。所以层的值在动画结束时已经是正确的。

percentScanned 需要设置为 @dynamic 变量,以便 Core Animation 为您实现访问器,根​​据