根据随机 CGFloat 值重新绘制 UIBezierPath
Posted
技术标签:
【中文标题】根据随机 CGFloat 值重新绘制 UIBezierPath【英文标题】:Re-draw UIBezierPath based on random CGFloat value 【发布时间】:2013-12-17 14:36:50 【问题描述】:我正在使用UIBezierPath
开发一个自定义的圆形进度条。我想根据随机生成的 CGFloat 值更改进度。
我的进度条是这样的:
我使用以下代码绘制了进度条:
// 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"];
我不知道如何重新绘制弧线,所以任何帮助或想法将不胜感激!
非常感谢。
花岗岩
【问题讨论】:
第一个建议:您的valueLabel
被吸引到了它的自我之上。尽量不要每次刷新都重新创建它,只需更改它的文本即可。其次,尝试重新使用子层或替换它。将arc
设为类变量。然后循环遍历子层,删除旧的arc
,然后用新的随机浮动百分比重新制作它。一旦arc
是一个类变量,那么您可以替换它并从零开始动画,或者您可以从它的当前百分比动画到新百分比。
@Putz1103 我将 arc 设为类变量,我正在重绘圆,它正在工作。你能回答让我接受吗? :) 谢谢
【参考方案1】:
尝试重新使用子层或替换它。使 arc 成为类变量。然后循环遍历子层,删除旧弧,然后用新的随机浮动百分比重新制作。一旦 arc 是一个类变量,那么您可以替换它并从零开始动画,或者您可以从它的当前百分比动画到新的百分比。
【讨论】:
以上是关于根据随机 CGFloat 值重新绘制 UIBezierPath的主要内容,如果未能解决你的问题,请参考以下文章
调用方式 - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 无需重新加
swift 3 中 swift 2 的 CGFloat.random(min: CGFloat, max: CGFloat) 是啥?