Repeating busy circle animation

断了今生、忘了曾经 提交于 2019-12-25 03:54:42

问题


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!


回答1:


To create a spinning animation, inside your createAnimations method, replace what you have with:

CABasicAnimation *spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
spinAnimation.byValue = [NSNumber numberWithFloat:2.0f*M_PI];
spinAnimation.duration = 1.3;
spinAnimation.repeatCount = HUGE_VALF;
[self.viewThatHasTheDrawings.layer addAnimation:spinAnimation forKey:@"indeterminateAnimation"];

This will spin the animation forever.

To cancel the animation, use:

[self.viewThatHasTheDrawings.layer removeAllAnimations];


来源:https://stackoverflow.com/questions/24998135/repeating-busy-circle-animation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!