0
votes

I am drawing a path in my UIView's drawRect method. In certain situations that path will go away and I want to animate this - let's call it "undrawing" of the path.

For the animation, I am creating a CAShapeLayer, give it myPath and then set up a CABasicAnimation (animationWithKeyPath:@"strokeEnd").

My problem is how to switch from what is drawn in drawRect to the animation. I have to remove myPath from what is drawn from drawRect and call setNeedsDisplay - otherwise the animation would be hidden by the path drawn from drawRect.

- (void)animationDidStart:(CAAnimation *)theAnimation
  {
    myPath = nil;
    [self setNeedsDisplay];
  }

But this way I see my path, then a quick flickering with no path, then the path is rendered by CoreAnimation again and is nicely undrawn.

Can I do better to avoid the flickering?

Background This is how I set up the animation:

- (void) startAnimation
{
  pathLayer.path = myPath.CGPath;
  pathLayer.hidden = false;

  CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
  pathAnimation.duration = 1; 
  pathAnimation.fromValue = [NSNumber numberWithFloat:1.0f];
  pathAnimation.toValue = [NSNumber numberWithFloat:0.0f];
  pathAnimation.fillMode = kCAFillModeForwards;
  pathAnimation.removedOnCompletion = NO;
  pathAnimation.delegate = self;
  [pathLayer addAnimation:pathAnimation forKey:@"strokeEnd"];
}
2
How have you set up your basic animation?David Rönnqvist
Added animation setup code to the question.Miriam
Would kCAFillModeBoth fix the flicker for you?David Rönnqvist
No change with kCAFillModeBoth.Miriam

2 Answers

1
votes

I believe the cause of the flickering is the implicit animation that runs when you call

pathLayer.hidden = NO;

By default, standalone CALayers animate most property changes implicitly. If you disable the implicit animation for the hidden property, it should run without flickering (regardless whether you use drawRect: or drawLayer:inContext:):

[CATransaction begin];
[CATransaction setDisableActions:YES];
pathLayer.hidden = NO;
[CATransaction commit];
0
votes

Here is my solution: Don't combine UIKits drawRect with CAAnimation but draw into a CALayer instead:

- (void)drawLayer:(CALayer *)theLayer inContext:(CGContextRef)theContext 

This allows flicker-free switching from drawing to animation.