I'm trying to build a pie chart animation with Core Animation, and I'm having trouble. I want to be able to animate it (hence the use of Core Animation) but also be able to turn animation off easily.
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated {
self.innerPie.hidden = NO;
self.innerPie.strokeEnd = progress;
if (animated) {
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
pathAnimation.duration = (animated) ? 2.0 : 0.0;
pathAnimation.fromValue = [NSNumber numberWithFloat:self.progress];
pathAnimation.toValue = [NSNumber numberWithFloat:progress];
[self.innerPie addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
}
self.progress = progress;
}
That's my code. If I set animated
to NO
, the animation still occurs, just much faster. Why? How would I change it so it's instant?
strokeEnd
is an animatable property of a layer - in this case, a CAShapeLayer (otherwise you could not attempt to animate using animationWithKeyPath
).
Well, setting a layer's animatable property animates the change! That is called (by me at least) implicit animation.
So this one line, all by itself, causes animation:
self.innerPie.strokeEnd = progress;
To prevent that, you must turn off implicit animation temporarily. There are various ways to do that; the usual thing is to disable it at the transaction level by calling the CATransaction class method setDisableActions:
(to YES, obviously).