Reputation: 616
I have a CAShapeLayer where I animate a circle. The animation is to first "undraw" the circle clockwise and then redraw the circle clockwise. Sort of a "rotating circle". Another way to put it: Move path stroke end point to start, then move the start point to the end.
The animation itself works, but it produces glitches now and then. It manifests in a short glimpse of the entire circle when it is supposed to be "undrawn".
Why does this occur and how can you fix it?
Thanks,
// Shape creation
layer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, self.width - 2 * OUTER_BORDER_WIDTH, self.width - 2* OUTER_BORDER_WIDTH)].CGPath;
// Animation queuing
-(void) applyNextAnimation
{
CABasicAnimation* animation;
if (self.animatingOpening)
{
animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
self.animatingOpening = NO;
}
else
{
animation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
self.animatingOpening = YES;
}
animation.duration = 1.0f;
animation.autoreverses = NO;
animation.delegate = self;
animation.removedOnCompletion = YES;
[self.outerCircleLayer addAnimation:animation forKey:@"stroke"];
}
// Animation stop callback
-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if (self.isAnimating)
{
[self applyNextAnimation];
}
}
Upvotes: 1
Views: 119
Reputation: 31745
It blinks becuase you are not setting the corresponding property on the layer. So when the animation completes, the layer's model is still in the pre-animated state and that is what you see momentarily between the two animations.
This will get you towards what you want...
if (self.animatingOpening)
{
self.outerCircleLayer.strokeStart = 0.0;
animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
self.animatingOpening = NO;
}
else
{
self.outerCircleLayer.strokeStart = 1.0;
animation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
self.animatingOpening = YES;
}
animation.duration = 1.0f;
animation.autoreverses = NO;
that almost works, but you will notice a more subtle glitch as you transition from the undrawn state to start animating the drawing state. The beginning of the circle has a small reverse animation as it starts. This is an implicit animation triggered by setting strokeStart from 1.0 to 0.0: which you need to get rid of so that all of the animations effects are under your control. You can achieve that most simply by setting disableActions to YES on CATransaction:
[CATransaction setDisableActions:YES];
( add it just above if (self.animatingOpening)
)
Upvotes: 1