I'm trying to create an arrow with rounded corners, but I'm not getting the result I want
private let arrowLayer: CAShapeLayer = {
let layer = CAShapeLayer()
layer.fillColor = UIColor.orange.cgColor
layer.anchorPoint = CGPoint(x: 0.2, y: 0.5)
layer.lineWidth = 4
layer.strokeColor = UIColor.orange.cgColor
layer.fillColor = UIColor.orange.cgColor
layer.lineCap = .round
layer.lineJoin = .round
return layer
}()
override func layoutSubviews() {
super.layoutSubviews()
arrowLayer.bounds.size = CGSize(width: bounds.width * 0.27, height: bounds.width * 0.02)
arrowLayer.position = CGPoint(x: bounds.midX, y: bounds.midY)
let path = UIBezierPath()
path.move(to: CGPoint(x: arrowLayer.bounds.width, y: arrowLayer.bounds.height * 0.3))
path.addLine(to: CGPoint(x: arrowLayer.bounds.width, y: arrowLayer.bounds.height * 0.7))
path.addLine(to: CGPoint(x: 0.0, y: arrowLayer.bounds.height))
path.addLine(to: CGPoint(x: 0.0, y: 0.0))
path.close()
arrowLayer.path = path.cgPath
}
This is the result I get
I want to get this result
I tried but didn't get the desired result
layer.lineCap = .round
layer.lineJoin = .round
You may need to draw arcs on both sides like:
let minR: CGFloat = 10
let bigR: CGFloat = 20
var path = UIBezierPath()
path.move(to: .init(x: rect.midX - minR, y: minR))
path.addArc(
withCenter: .init(x: rect.midX, y: minR),
radius: minR,
startAngle: .degrees(0),
endAngle: .degrees(180),
clockwise: true
)
path.addLine(to: .init(x: rect.midX - bigR, y: rect.maxY - bigR))
path.addArc(
withCenter: .init(x: rect.midX, y: rect.maxY - bigR),
radius: bigR,
startAngle: .degrees(0),
endAngle: .degrees(180),
clockwise: false
)
path.move(to: .init(x: rect.midX + bigR, y: rect.maxY - bigR))
path.addLine(to: .init(x: rect.midX + minR, y: minR))
path.addLine(to: .init(x: rect.midX - minR, y: minR))
path.addLine(to: .init(x: rect.midX - bigR, y: rect.maxY - bigR))
Don't forget to convert radians to degrees:
extension CGFloat {
static func degrees(_ degrees: Double) -> Double { degrees * .pi / 180 }
}