如何将UIBezierPath线条边缘进行圆角处理?

5

我有一条由UIBezierPath绘制的线:

let line = CAShapeLayer()
line.path = UIBezierPath(arcCenter: center,
                          radius: radius,
                          startAngle: CGFloat(114.0/180.0) * .pi,
                          endAngle: .pi,
                          clockwise: true).cgPath
line.lineWidth = LINE_WIDTH
line.strokeColor = UIColor.red.withAlphaComponent(0.9).cgColor
line.fillColor = UIColor.clear.cgColor

我尝试通过添加一些新的CAShapeLayer()来圆角:

let corner = CAShapeLayer()
corner.path = UIBezierPath(arcCenter: coordByCorner(114.0*1.00035),
                           radius: LINE_WIDTH/2,
                           startAngle: CGFloat(114.0/180.0) * .pi,
                           endAngle: CGFloat(114.0/180.0 + 1) * .pi,
                           clockwise: false).cgPath
corner.strokeColor = UIColor.clear.cgColor
corner.fillColor = UIColor.red.withAlphaComponent(0.9).cgColor

line.addSublayer(corner)

但我认为这是一种糟糕的变体,当我更改层的颜色时,颜色会随着不同的时间间隔而发生变化。

此外,所有这些看起来都像这样:

enter image description here

附言:1.00035是为了消除层之间的间隙。Alpha需要小于1.0(0.1-0.9)。那么如何在保持alpha的情况下做到这一点?


在编辑之后,你的问题与原始问题完全不同,这导致之前所有的回答都无效了。记住,回答的目的主要是为了帮助将来遇到类似问题的访问者。原始问题已经解决了,应该提出一个不同的问题,请考虑单独发布它。 - Tomasz Pe
Fayer,最初的问题已经解决了,但那只是一个“权宜之计”。在我尝试更改答案代码并添加问题信息后,问题始终保持不变,因此我认为更改正确答案没有问题,因为只要我更改问题信息,我的问题就无法永久解决。 - Golovanov Dmytrii
3个回答

13

通过添加kCALineCapRound解决了问题

let line = CAShapeLayer()
line.path = UIBezierPath(arcCenter: center,
                      radius: radius,
                      startAngle: CGFloat(114.0/180.0) * .pi,
                      endAngle: .pi,
                      clockwise: true).cgPath
line.lineWidth = LINE_WIDTH
line.strokeColor = UIColor.red.withAlphaComponent(0.9).cgColor
line.fillColor = UIColor.clear.cgColor
line.lineCap = kCALineCapRound // this parameter solve my problem

在Swift 5中的.round - Juan Boero
1
如果我想要cornerRadius为8怎么办? - Twitter khuong291

1
一种简单的方法是创建向内偏移所需 cornerRadius 的路径,用两倍粗的线条描边,并应用圆角线连接样式。
let layer = CAShapeLayer()

layer.strokeColor = UIColor.lightGray.cgColor
layer.fillColor = UIColor.lightGray.cgColor
layer.lineWidth = 2.0 * cornerRadius
layer.lineJoin = kCALineJoinRound
layer.path = getSemicirclePath(
    arcCenter: arcCenter,
    radius: radius,
    cornerRadius: cornerRadius
)

func getSemicirclePath(arcCenter: CGPoint, radius: CGFloat, cornerRadius: CGFloat) -> CGPath {
    let path = UIBezierPath(
        arcCenter: CGPoint(x: arcCenter.x, y: arcCenter.y - cornerRadius),
        radius: radius - cornerRadius,
        startAngle: .pi,
        endAngle: 2.0 * .pi,
        clockwise: true
    )
    path.close()
    return path.cgPath
}

这是一个示例结果:

enter image description here


如何使此元素不透明?(需要使用alpha <1.0的UIColor) - Golovanov Dmytrii

-1

根据当前版本,另一种方法是

line.path.lineCapStyle = .round

你是指 line.lineCap = .round 还是 line.lineJoin = .round - HangarRash
打错了。 我的意思是 line.path.lineCapStyle = .round - hpDev_iOS
但是CGPath没有lineCapStyle属性。lineCAShapeLayerline.pathCGPath? - HangarRash
你应该编辑你的回答使其正确。 - HangarRash

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