Search code examples
iosobjective-ccocoa-touchcore-animationcalayer

Why am I unable to make my animation duration 0 seconds? How would I correctly do it?


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?


Solution

  • 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).