CAShapeLayer 和 UIBezierPath 逆时针绘制圆的问题

Bor*_*nko 3 cashapelayer uibezierpath swift

我正在尝试画一个以逆时针方向 12 点钟开始和结束的圆圈。我遇到的问题是形状没有被绘制。我使用init(arcCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool)路径初始化程序,如果我使用clockwise: true,它就可以工作。如果startAngle设置为0endAngleto2 * .pi它适用于clockwise: false. clockwise: false然而和的组合startAngle: -0.5 * .pi, endAngle: 1.5 * .pi不起作用。这是有原因的吗?我该如何解决?

这个有效:

let shapeLayer = CAShapeLayer()
let arcCenter = view.center
let circularPath = UIBezierPath(arcCenter: arcCenter, radius: 100, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: false)
shapeLayer.path = circularPath.cgPath
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 10
shapeLayer.lineCap = .round
shapeLayer.fillColor = .none
view.layer.addSublayer(shapeLayer)
Run Code Online (Sandbox Code Playgroud)

和这个。结果看起来一样。

UIBezierPath(arcCenter: arcCenter, radius: 100, startAngle: -0.5 * .pi, endAngle: 1.5 * .pi, clockwise: true)
Run Code Online (Sandbox Code Playgroud)

成功

但不是这个:

UIBezierPath(arcCenter: arcCenter, radius: 100, startAngle: -0.5 * .pi, endAngle: 1.5 * .pi, clockwise: false)
Run Code Online (Sandbox Code Playgroud)

失败的

ahe*_*eze 6

用度来思考这个问题更容易。

  • -0.5 * .pi弧度等于-90度数
  • 1.5 * .pi弧度等于270度数
  • 0度数位于圆的右中位置

然而,如果你仔细想想,-90它们270在圆上的位置是一样的。


clockwise = true:

UIBezierPath(arcCenter: arcCenter, radius: 100, startAngle: -0.5 * .pi, endAngle: 1.5 * .pi, clockwise: true)
Run Code Online (Sandbox Code Playgroud)

clockwise = false:

UIBezierPath(arcCenter: arcCenter, radius: 100, startAngle: -0.5 * .pi, endAngle: 1.5 * .pi, clockwise: false)
Run Code Online (Sandbox Code Playgroud)

那么为什么画clockwise得很远,而逆时针却不能呢?看看这个: 逐渐增加弧角

如果您在圆上选取两个点(或者您可以说角度)并逐渐增加其中一个点,您可以看到环如何根据其是否移动 / 来延长/clockwise缩短counterclockwise。这些戒指相得益彰——如果你把clockwise戒指放在戒指的上面counterclockwise,它们就会完美地组合成一个圆圈。

因此,当您增加终点以使其等于起点 ( start: -90, end: 270) 时:

  • 戒指clockwise将充满
  • 戒指counterclockwise将是空的

而当你切换负数 ( start: 90, end: -270) 时:

  • 戒指clockwise将是空的
  • 戒指counterclockwise将充满

另外,这里有一个方便的扩展(感谢@Leo Dabus!),这样您就不必再处理弧度了:

extension BinaryInteger {
    var degreesToRadians: CGFloat { CGFloat(self) * .pi / 180 }
}

extension FloatingPoint {
    var degreesToRadians: Self { self * .pi / 180 }
    var radiansToDegrees: Self { self * 180 / .pi }
}

/// usage:
UIBezierPath(arcCenter: arcCenter, radius: 100, startAngle: -90.degreesToRadians, endAngle: 270.degreesToRadians, clockwise: true)
Run Code Online (Sandbox Code Playgroud)

  • `0*.pi` 到 `2*.pi` 和 `1*.pi` 到 `3*.pi` 有什么区别?我不明白。`-90` 和 `270` 不是同一个角度。如果这是真的,“0”和“360”也可以。 (2认同)
  • 所以如果顺时针方向增加数值就满了,如果逆时针减小数值就满了。现在这对我来说完全有道理。 (2认同)