【问题标题】:Draw circle with UIBezierPath用 UIBezierPath 画圆
【发布时间】:2014-09-23 10:25:04
【问题描述】:

我正在尝试使用 UIBezierPath addArcWithCenter 方法画一个圆:

UIBezierPath *bezierPath = 
  [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0., 0., 100., 100.)];

[bezierPath addArcWithCenter:center 
                      radius:0. 
                  startAngle:0 endAngle:2 * M_PI clockwise:YES];

CAShapeLayer *progressLayer = [[CAShapeLayer alloc] init];

[progressLayer setPath:bezierPath.CGPath];
[progressLayer setStrokeColor:[UIColor colorWithWhite:1. alpha:.2].CGColor];
[progressLayer setFillColor:[UIColor clearColor].CGColor];
[progressLayer setLineWidth:.3 * self.bounds.size.width];
[progressLayer setStrokeStart:_volumeValue/100.];
[progressLayer setStrokeEnd:volume/100.]; // between 0 and 100

[_circleView.layer addSublayer:progressLayer];

但我得到的是以下内容:

我尝试使用不同的参数,但没有运气

谢谢

更新:

如果我没有解释我想要做什么,我很抱歉:

*背景圆是用 :

绘制的
[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0., 0., 100., 100.)]

*我正在尝试使用 bezierPathWithOvalInRect 逐步绘制红色圆圈 两个值之间:_volumeValue 和 volume

但我不能得到一个完美的圆,而是在一定值之后得到水平部分。

【问题讨论】:

  • 哪个位不工作?对我来说,它看起来像一个圆圈。你能从图片中去除多余的“噪音”,只显示你感兴趣的东西吗?
  • 另外,volume_volumeValue 是什么?
  • 不清楚你想做什么。
  • 好多了,我想我已经发现了。添加了答案。 :)

标签: objective-c calayer cashapelayer cabasicanimation


【解决方案1】:

好的,试试这个……

UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath addArcWithCenter:center radius:50 startAngle:0 endAngle:2 * M_PI clockwise:YES];

CAShapeLayer *progressLayer = [[CAShapeLayer alloc] init];
[progressLayer setPath:bezierPath.CGPath];
[progressLayer setStrokeColor:[UIColor colorWithWhite:1.0 alpha:0.2].CGColor];
[progressLayer setFillColor:[UIColor clearColor].CGColor];
[progressLayer setLineWidth:0.3 * self.bounds.size.width];
[progressLayer setStrokeEnd:volume/100];
[_circleView.layer addSublayer:progressLayer];

volume 应该在 0 到 100 之间。

另外,您正在创建一条带有椭圆的路径,然后向其添加弧线。不要那样做。只需将圆弧添加到空路径即可。

如果您想更改圆弧的起点,请在添加圆弧时更改startAngleendAngle。不要更改笔画起始值。

动画变化

[CATransaction begin];
CABasicAnimation *animateStrokeDown = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animateStrokeDown.toValue = [NSNumber numberWithFloat:volume/100.];
[progressLayer addAnimation:animateStrokeDown forKey:@"animateStrokeDown"];
[CATransaction commit];

好的,这将为路径的strokeEnd 属性设置动画。你必须意识到,它是这样工作的......

Begin state: start = 0, end = 6
0123456
-------

// increase volume
Animate to: end = 9
0123456789
----------

// decrease volume
Animate to: end = 1
01
--

起点没有移动。结局已经动了。您没有“填写”该行的其余部分。你正在换行。

这就是为什么 start 应该始终为 0 而您只需更改笔画 end。

【讨论】:

  • 将圆弧添加到空路径有帮助,但为什么不指定 strokeStart 和 strokeEnd 呢?因为我想对这两个值之间的变化进行动画处理,并在下一次调用中从 strokeEnd 点开始。
  • 这里是动画的代码:[CATransaction begin]; CABasicAnimation *animateStrokeDown = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; animateStrokeDown.fromValue = [NSNumber numberWithFloat:_volumeValue/100.]; animateStrokeDown.toValue = [NSNumber numberWithFloat:volume/100.]; animateStrokeDown.removedOnCompletion = YES; [progressLayer addAnimation:animateStrokeDown forKey:@"animateStrokeDown"]; [CATransaction commit];
  • 嗯...你想有一个音量滑块的东西吗?因此,如果全音量和半音量等半圆,它将显示一个完整的圆圈?圈子的起点肯定不应该移动吗?啊!我想我一秒钟就明白了……
  • 是的,完全是圆形音量幻灯片,带有动画音量变化:)
  • @Mosbah 好的,不。你只需要一层。它有整个圆圈。你改变那个圈子。应该只有一层。即一层,一个圆圈,为该圆圈的端点设置动画。
【解决方案2】:
startAngle:degreesToRadians(-90) endAngle:0 clockwise:YES

(原因是iOS默认坐标系x轴向右,y轴向下)

阅读这份文件 https://developer.apple.com/library/ios/documentation/uikit/reference/UIBezierPath_class/index.html

指定起始角为 0 弧度,结束角为 π 弧度,并将顺时针参数设置为 YES 绘制圆的下半部分。但是,指定相同的开始和结束角度但将顺时针参数设置为 NO 会绘制圆的上半部分。

【讨论】:

  • 这不会导致圆圈。
【解决方案3】:

我不知道您期望什么以及您的实际结果有什么问题 - 但是您的第二行代码中的 0 半径看起来很可疑。它只是将center 处的一个点添加到当前路径(其中已经包含一个圆圈)。

【讨论】:

  • 你是完全正确的,半径的逻辑值是 50。但奇怪的是,即使我改变了这个值,我总是得到相同的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多