REPRO repository here: https://github.com/kaolin/38492498/tree/master
I have a @property int percentScanned
.
I've set needsDisplayForKey:
+ (BOOL)needsDisplayForKey:(NSString *)key {
if ([@"percentScanned" isEqualToString:key]) {
return YES;
}
return [super needsDisplayForKey:key];
}
My display method:
- (void)display {
_percentTextLayer.string = [NSString stringWithFormat:@"%02d%%",[[self presentationLayer] percentScanned]];
}
My animation:
[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];
This all works fine, except at the end of the animation, my model layer string goes back to "00%". As you can see, I've thrown what feels like the kitchen sink at forcing it to stay at "99%" (outside of the "hack" of animation.removedOnCompletion = NO;
and animation.fillMode = kCAFillModeForwards;
—and actually, adding those doesn't help!).
I do have another animation on the same layer about 3/30 of a second later, fading the opacity.... But pushing that out, or deleting it, doesn't seem to make a difference.
I know how to do this for standard animated values, but I'm missing something for how to do this with a secondary/evaluated value like this....
EDITED TO ADD:
Somewhere along the way, adding animation.removedOnCompletion = NO;
and animation.fillMode = kCAFillModeForwards;
did actually start "working", but I'd like to not leak animations....
If I add a setter for percentScanned, it's not called with 0 at the end, but display is called with 0 at the end. It's kind of hard to trace the link between setPercentScanned being called and display being called...
I can hack my display
to read as follows:
- (void)display {
if ([[self presentationLayer] percentScanned] != 0) {
_percentTextLayer.string = [NSString stringWithFormat:@"%02d%%",[[self presentationLayer] percentScanned]];
}
}
Then it works for my particular use case, but that's still less than ideal....
And putting a breakpoint in the display method is fairly unhelpful (of course it's just happening inside display_if_needed). :/