Search code examples
iosuinavigationcontrollercore-animationcabasicanimationcaanimation

CABasicAnimation resets when edge swiping with UINavigationController


I have the following CABasicAnimation run in my viewDidLoad for a view controller inside a UINavigationController:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.duration = 1;
animation.additive = NO;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.fromValue = [NSNumber numberWithFloat:0];
animation.toValue = [NSNumber numberWithFloat:-1*(((-windBearing+180) * M_PI) / 180)];
[compass.layer addAnimation:animation forKey:@"90rotation"];

When I use the edge swipe gesture to slowly navigate back, the animation resets to the initial state, which is quite jarring. I have my fillMode set and removedOnCompletion set to NO, what am I missing?


Solution

  • This whole trick of setting the fillMode and the removedOnCompletion is nonsense - it's bad advice that has worked itself into a lot of answers, but it's totally wrong. The animation is one thing; the actual transform of the compass layer is another. You have applied the animation but you have forgotten to set the transform to match it. Therefore, when the gesture starts and the animation is removed from the layer, the compass is shown at its actual rotation (and the change appears as a jump).