UIBezierPath的起始角度和结束角度是什么?

13

我使用UIBezierPathCAShapeLayer在iOS中编写了以下半圆代码:

 clockWiseLayer = [[CAShapeLayer alloc] init];

CGFloat startAngle = -M_PI_2;
CGFloat endAngle = M_PI + M_PI_2;

CGFloat width = CGRectGetWidth(imageView.frame)/2.0f + 30;
CGFloat height = CGRectGetHeight(imageView.frame)/2.0f +50;
CGPoint centerPoint = CGPointMake(width, height);

float radius = CGRectGetWidth(imageView.frame)/2+10;

clockWiseLayer.path = [UIBezierPath bezierPathWithArcCenter:centerPoint
                                                    radius:radius
                                                startAngle:startAngle
                                                  endAngle:endAngle
                                                 clockwise:YES].CGPath;

clockWiseLayer.fillColor = [UIColor clearColor].CGColor;
clockWiseLayer.strokeColor = [UIColor blueColor].CGColor;
clockWiseLayer.borderColor = [UIColor greenColor].CGColor;
clockWiseLayer.backgroundColor = [UIColor redColor].CGColor;

clockWiseLayer.strokeStart = 0.0f;
clockWiseLayer.strokeEnd = 0.5f;

clockWiseLayer.lineWidth = 2.0f;
clockWiseLayer.borderWidth = 5.0f;

clockWiseLayer.shouldRasterize = NO;
[self.layer addSublayer:clockWiseLayer];

以下是结果。

enter image description here

我希望这个蓝色的半圆在地球仪的相反面。

它是半圆,但我想要它在另一面,而且是逆时针方向。

clockwise:NO时,我无法为其设置起始角度和终止角度。

谢谢。


你尝试过从M_PI_2开始,以M_PI_2 + M_PI结束吗? - Grzegorz Krukowski
是的,我做了,但没有用。它并不完全相反。 - Sam Shaikh
“我无法为此设置起始和结束角度,同时顺时针为NO”,你的意思是什么?它不能画出半圆吗?它会崩溃吗?还是其他什么问题? - Avt
它没有崩溃,但它没有像我期望的那样显示结果。如果我对顺时针说“不”,它将在相同的起始和结束角度处感到惊讶(从视图中隐藏)@Avt - Sam Shaikh
4个回答

34

检查坐标的文档: http://i.stack.imgur.com/1yJo6.png

enter image description here

与数学标准坐标系相比,Y轴是反向的。

您应该从1/2 * PI(底部锚点)绘制到3/2 * PI(顶部锚点),然后将strokeStart设置为0.0f,将strokeEnd设置为1.0f(以便填充整个路径)。

使用iOS常量的工作代码:

CGFloat startAngle = M_PI_2;
CGFloat endAngle = startAngle + M_PI;
CGFloat width = CGRectGetWidth(imageView.frame)/2.0f;
CGFloat height = CGRectGetHeight(imageView.frame)/2.0f;
CGPoint centerPoint = CGPointMake(width, height);
float radius = CGRectGetWidth(imageView.frame)/2+10;
CAShapeLayer* clockWiseLayer = [[CAShapeLayer alloc] init];
clockWiseLayer.path = [UIBezierPath bezierPathWithArcCenter:centerPoint
                                                     radius:radius
                                                 startAngle:startAngle
                                                   endAngle:endAngle
                                                  clockwise:YES].CGPath;

clockWiseLayer.fillColor = [UIColor clearColor].CGColor;
clockWiseLayer.strokeColor = [UIColor blueColor].CGColor;
clockWiseLayer.borderColor = [UIColor greenColor].CGColor;
clockWiseLayer.backgroundColor = [UIColor redColor].CGColor;

clockWiseLayer.strokeStart = 0.0f;
clockWiseLayer.strokeEnd = 1.0f;

clockWiseLayer.lineWidth = 2.0f;
clockWiseLayer.borderWidth = 5.0f;
[self.layer addSublayer:clockWiseLayer];

2
如果我想将一个圆从顶部逆时针移动,起始角度和结束角度应该是多少?请帮忙。 - Kunal Gupta
@DilipTiwari,你需要做的就是使用不同的startAngle和endAngle - 其余保持不变。endAngle将是startAngle + 2*M_PI,而startAngle如上所述为M_PI+M_PI_2。 - Grzegorz Krukowski

7

你需要从圆的顶部开始,起始角度为-M_PI_2,结束角度为M_PI + M_PI_2(如果你想绘制完整的圆并使用strokeEndstrokeStart进行限制)。然后将圆形路径设置为从路径末尾的一半(图像左侧)开始绘制,而不是从开头到一半(图像右侧)。

CGFloat startAngle = -M_PI_2;
CGFloat endAngle = M_PI + M_PI_2;

clockWiseLayer.strokeStart = .5f;
clockWiseLayer.strokeEnd = 1.0f;

1
我已经使用了bezierPathWithArcCenter,如果clockwise = NO它的工作方式非常奇怪。但是如果您想要创建一个逆时针方向的圆形贝塞尔路径,您可以创建一个顺时针路径,然后使用bezierPathByReversingPath反转它。

一个新的路径对象,具有相同的路径形状,但是该路径是以相反方向创建的。


0

这个函数可以帮助设置圆中弧的起始位置和结束位置。

func fillProgress(from currentValue: Double, to finalValue: Double, with duration: TimeInterval) {
    let startAngle = CGFloat(-Double.pi / 2)
    let completionPercentage = currentValue / Double(finalValue)
    let endAngle = startAngle + (2 * .pi * completionPercentage)
    
    let circularPath = UIBezierPath(
        arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0),
        radius: frame.width / 2 - circleLineWidth / 2,
        startAngle: startAngle,
        endAngle: endAngle,
        clockwise: true
    )
    
    let circleLayer = CAShapeLayer()
    circleLayer.path = circularPath.cgPath
    circleLayer.fillColor = UIColor.clear.cgColor
    circleLayer.lineCap = .square
    circleLayer.lineWidth = circleLineWidth
    circleLayer.strokeEnd = 0.0
    circleLayer.strokeColor = UIColor.clear.cgColor
    layer.addSublayer(circleLayer)

    let progressLayer = CAShapeLayer()
    progressLayer.path = circularPath.cgPath
    progressLayer.fillColor = UIColor.clear.cgColor
    progressLayer.lineCap = .square
    progressLayer.lineWidth = circleLineWidth
    progressLayer.strokeEnd = 0
    progressLayer.strokeColor = R.color.color_82C9AD()?.cgColor
    layer.addSublayer(progressLayer)
    
    // Animate
    let circularProgressAnimation = CABasicAnimation(keyPath: "strokeEnd")
    circularProgressAnimation.duration = duration
    circularProgressAnimation.toValue = 1.0
    circularProgressAnimation.fillMode = .forwards
    circularProgressAnimation.isRemovedOnCompletion = false
    progressLayer.add(circularProgressAnimation, forKey: "progressAnim")
}

}

这里的circleLineWidth可以有自定义值,表示所需弧线的粗细程度。 finalValue是代表整个圆的值,即360度。 currentValuefinalValue中的一个数值。

弧线将从零(顶部)绘制到currentValue


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接