I need to draw a rounded rect. However, at very special corner radius values (between 34 to 37), it causes very strange bugs like the image below. Can someone explain to me why it happened?
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
drawView()
self.view.backgroundColor = .red
}
func drawView() {
let rect = CGRect(x: 100, y: 100, width: 200, height: 100)
let borderWidth = 10.0
let cornerRadius = 34.0
let layer = CAShapeLayer()
layer.strokeColor = UIColor.green.cgColor
layer.lineWidth = borderWidth
layer.fillColor = UIColor.white.cgColor
let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
layer.path = path.cgPath
self.view.layer.addSublayer(layer)
}
}
2
Answers
Using 2 bezierpath and fill with color instead of using single path with stroke.
The problem is CALayer using multiple path to create a border, cause overlap between the path then it mixed with fill rule .evenOdd cause weird behavior. This also make impossible to create a perfect circle.
This article explained why is it happened.
https://www.paintcodeapp.com/blogpost/code-for-ios-7-rounded-rectangles
Thanks Zalo iOS VietNam team to help me understand this.
My solution to avoid overlap by using 2 separated paths and fill color between them.
The another way to fix is using CGMutablePath.
I suspect that a rounded rectangle is implemented by joining some curves together and the artifact that you are seeing is caused by the
lineJoin
property of the layer.Setting
lineJoin
to.round
fixes it for me: