Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to round UIBezierPath line edge?

I have a line drawer by 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

I try to round corner by adding some new 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)

But I think this is so bad variant, and when I change colors for layers, colors changes with different timeInterval.

Also, this all look like this:

enter image description here

P.S.: 1.00035 there is for remove the gap between layers. And alpha need to be < 1.0 (0.1 - 0.9), so how do its opaque?

like image 953
Golovanov Dmytrii Avatar asked Dec 13 '22 18:12

Golovanov Dmytrii


2 Answers

Problem solved by adding 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
like image 73
Golovanov Dmytrii Avatar answered Dec 26 '22 20:12

Golovanov Dmytrii


A simple way of doing this is to create path shifted inwards by the desired cornerRadius, stroke it with the twice as thick line and apply rounded line joining style.

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
}

Here is the example result:

enter image description here

like image 45
Tomasz Pe Avatar answered Dec 26 '22 19:12

Tomasz Pe