基于随机CGFloat值重新绘制UIBezierPath
问题描述:
我正在开发一个使用UIBezierPath
的自定义圆形进度条。我想根据随机生成的CGFloat值更改进度。基于随机CGFloat值重新绘制UIBezierPath
我的进度条是这样的:
我用下面的代码提请进度条:
// Draw the arc with bezier path
int radius = 100;
CAShapeLayer *arc = [CAShapeLayer layer];
arc.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 50) radius:radius startAngle:M_PI endAngle:M_PI/150 clockwise:YES].CGPath;
arc.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius,
CGRectGetMidY(self.view.frame)-radius);
arc.cornerRadius = 100.0;
arc.fillColor = [UIColor clearColor].CGColor;
arc.strokeColor = [UIColor purpleColor].CGColor;
arc.lineWidth = 6;
[self.view.layer addSublayer:arc];
// Animation of the progress bar
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawAnimation.duration = 5.0; // "animate over 10 seconds or so.."
drawAnimation.repeatCount = 1.0; // Animate only once..
drawAnimation.removedOnCompletion = YES; // Remain stroked after the animation..
drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
drawAnimation.toValue = [NSNumber numberWithFloat:10.0f];
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[arc addAnimation:drawAnimation forKey:@"drawCircleAnimation"];
// Gradient of progress bar
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.view.frame;
gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,(__bridge id)[UIColor yellowColor].CGColor,(__bridge id)[UIColor purpleColor].CGColor ];
gradientLayer.startPoint = CGPointMake(0,0.1);
gradientLayer.endPoint = CGPointMake(0.5,0.2);
[self.view.layer addSublayer:gradientLayer];
gradientLayer.mask = arc;
refreshButton = [[UIButton alloc] initWithFrame:CGRectMake(50, 370, 50, 50)];
[refreshButton addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventTouchUpInside];
[refreshButton setBackgroundImage:[UIImage imageNamed:@"refresh.png"] forState:UIControlStateNormal];
[self.view addSubview:refreshButton];
的UIButton的用绿色箭头随机生成CGFloat的值。所以我的问题是如何重置动画,以便它停在相应的位置,如果它在0.0和1.0之间?我尝试在按钮的方法内部插入动画的代码,但是结果是新的弧线被绘制在现有的弧线的顶部。
-(void)refresh:(id)sender{
NSLog(@"Refresh action:");
CGFloat randomValue = (arc4random() % 256/256.0);
NSLog(@"%f", randomValue);
valueLabel.text = @"";
valueLabel = [[UILabel alloc] initWithFrame:CGRectMake(150, 370, 100, 50)];
valueLabel.text = [NSString stringWithFormat: @"%.6f", randomValue];
[self.view addSubview:valueLabel];
// Draw the arc with bezier path
int radius = 100;
CAShapeLayer *arc = [CAShapeLayer layer];
arc.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 50) radius:radius startAngle:M_PI endAngle:M_PI/150 clockwise:YES].CGPath;
arc.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius,
CGRectGetMidY(self.view.frame)-radius);
arc.cornerRadius = 100.0;
arc.fillColor = [UIColor clearColor].CGColor;
arc.strokeColor = [UIColor purpleColor].CGColor;
arc.lineWidth = 6;
[self.view.layer addSublayer:arc];
// Animation of the progress bar
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawAnimation.duration = 5.0; // "animate over 10 seconds or so.."
drawAnimation.repeatCount = 1.0; // Animate only once..
drawAnimation.removedOnCompletion = YES; // Remain stroked after the animation..
drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
drawAnimation.toValue = [NSNumber numberWithFloat:randomValue];
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[arc addAnimation:drawAnimation forKey:@"drawCircleAnimation"];
}
我不知道如何重新划出弧线,所以任何帮助或想法,将不胜感激!
非常感谢。
Granit
答
尝试重新使用子图层或替换它。使弧成为类变量。然后循环遍历子层,删除旧的弧,然后用新的随机浮动百分比重新制作。一旦arc是一个类变量,那么您可以替换它并从零开始动画,或者您可以将其当前百分比设置为新的百分比。
第一个建议:你的'valueLabel'正在绘制自己的顶部。尽量不要每刷新一次重新创建一次,而只是改变它的文本。其次,尝试重新使用子图层或替换它。使'arc'成为一个类变量。然后循环遍历子层,删除旧的“弧”,然后用新的随机浮动百分比重新制作。一旦'arc'是一个类变量,那么你可以替换它并且从零开始动画,或者你可以从它的当前百分比动画到一个新的百分比。 – Putz1103
@ Putz1103我让弧变成了一个类变量,我正在重绘这个圆并且它正在工作。你能回答,我可以接受吗? :) 谢谢 – Granit