I am currently trying to create a busy animation that looks like this:
The broken part of the loop continually spins around the circle to signal that an operation is in progress.
I am defining two circles using CAShapeLayer, one circle is 'filling in' the circle with strokeEnd and the other is 'clearing' with strokeStart. The 'clearing circle' starts 1/10 of the way in front of the 'filling circle':
NSInteger radius = self.frame.size.width / 2;
CGFloat lineWidth = radius / 7.5;
UIColor *color = [UIColor redColor];
//add the outer circle
_outerCircle1 = [CAShapeLayer layer];
_outerCircle1.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius) cornerRadius:radius].CGPath;
_outerCircle1.position = CGPointMake(0, 0);
_outerCircle1.strokeStart = 1;
_outerCircle1.fillColor = [UIColor clearColor].CGColor;
_outerCircle1.strokeColor = color.CGColor;
_outerCircle1.lineWidth = lineWidth;
[self.layer addSublayer:_outerCircle1];
_outerCircle2 = [CAShapeLayer layer];
_outerCircle2.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius) cornerRadius:radius].CGPath;
_outerCircle2.position = CGPointMake(0, 0);
_outerCircle2.strokeEnd = 0;
_outerCircle2.fillColor = [UIColor clearColor].CGColor;
_outerCircle2.strokeColor = color.CGColor;
_outerCircle2.lineWidth = lineWidth;
[self.layer addSublayer:_outerCircle2];
[self createAnimations];
Here is where I define the animations. When the 'clearing circle' gets all the way around the the circle, I have to start a new animation that finishes the rest of the animation, then starts the animation all over again:
- (void)createAnimations {
[CATransaction begin];
[CATransaction setCompletionBlock:^{
[CATransaction begin];
[CATransaction setCompletionBlock:^{
[self createAnimations];
}];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.duration = .5;
animation.fromValue = [NSNumber numberWithFloat:.9];
animation.toValue = [NSNumber numberWithFloat:1];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[_outerCircle2 addAnimation:animation forKey:@"fillingAnimation"];
animation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
animation.duration = .5;
animation.fromValue = [NSNumber numberWithFloat:0];
animation.toValue = [NSNumber numberWithFloat:.1];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[_outerCircle2 addAnimation:animation forKey:@"clearingAnimation"];
[CATransaction commit];
}];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.duration = 5;
animation.fromValue = [NSNumber numberWithFloat:0];
animation.toValue = [NSNumber numberWithFloat:.9];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[_outerCircle2 addAnimation:animation forKey:@"fillingAnimation"];
animation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
animation.duration = 5;
animation.fromValue = [NSNumber numberWithFloat:.1];
animation.toValue = [NSNumber numberWithFloat:1];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[_outerCircle1 addAnimation:animation forKey:@"clearingAnimation"];
[CATransaction commit];
}
This code has the desired effect of continually animating the circle, but each time the completion block is triggered for either the main animation or the follow up animation, the animations stutter.
I am not sure of the best way to perform this animation. Can anyone help me improve it?? Thanks!