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

问题描述

我正在尝试绘制一个以逆时针方向开始和结束于12点的圆圈。我遇到的问题是未绘制形状。 我在路径中使用init(arcCenter center: CGPoint,radius: CGFloat,startAngle: CGFloat,endAngle: CGFloat,clockwise: Bool)初始化程序,如果使用clockwise: true,则可以使用。如果将startAngle设置为0,并且将endAngle设置为2 * .pi,则它将与clockwise: false一起使用。但是clockwise: falsestartAngle: -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)

还有这个。结果看起来一样。

UIBezierPath(arcCenter: arcCenter,startAngle: -0.5 * .pi,endAngle: 1.5 * .pi,clockwise: true)

Success

但不是这个:

UIBezierPath(arcCenter: arcCenter,clockwise: false)

Failed

解决方法

以度为单位进行思考更容易。

  • -0.5 * .pi弧度等于-90
  • 1.5 * .pi弧度等于270
  • 0度在圆的右中角

但是,如果您考虑一下,-90270在圆上的位置相同。


clockwise = true

UIBezierPath(arcCenter: arcCenter,radius: 100,startAngle: -0.5 * .pi,endAngle: 1.5 * .pi,clockwise: true)

clockwise = false

UIBezierPath(arcCenter: arcCenter,clockwise: false)

那么clockwise是如何走得很远的,而逆时针却没有呢?看看这个: gradually increasing arc angles

如果您在圆上选择两个点(或者可以说成角度)并逐渐增加其中一个,则可以根据环clockwise / counterclockwise的角度来了解环的延长/缩短。环彼此互补-如果将clockwise环放在counterclockwise环的顶部,它们会完美地组合成一个圆圈。

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

  • clockwise环将满
  • counterclockwise环将为空

而当您切换负片(start: 90,end: -270)时:

  • clockwise环将为空
  • counterclockwise环将满

此外,这里还有一个方便的extension(感谢@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,startAngle: -90.degreesToRadians,endAngle: 270.degreesToRadians,clockwise: true)