I'm trying to merge two overlapping UIBezierPaths using UIBezierPath.append
, and I want the overlapping space to be filled. I tried setting the usesEvenOddFillRule
property to false
, but it still doesn't fill. Here is minimal example of the problem:
override func draw(_ rect: CGRect) {
let firstShape = UIBezierPath()
firstShape.move(to: CGPoint(x: 100, y: 100))
firstShape.addLine(to: CGPoint(x: 100, y: 150))
firstShape.addLine(to: CGPoint(x: 150, y: 170))
firstShape.close()
let secondShape = UIBezierPath(rect: CGRect(x: 125, y: 125, width: 75, height: 75))
let combined = UIBezierPath()
combined.append(firstShape)
combined.append(secondShape)
UIColor.black.setFill()
combined.fill()
}
This yields the following shape:
What I would like it to look like:
This problem also seems to occur when using move(to: CGPoint)
on one UIBezierPath. If you would draw both these shapes on the same UIBezierPath, the same problem would occur.
Does anyone know how to make the overlapping region filled? Preferably the solution would also work when doing addClip()
You were on the right track with setting the usesEvenOddFillRule
to false. In addition to that, you need to make sure your shapes are both drawn in the same direction (clockwise or counter-clockwise).
I reversed the order of your addLine
s when drawing the triangle to reverse it.
override func draw(_ rect: CGRect) {
let firstShape = UIBezierPath()
firstShape.move(to: CGPoint(x: 100, y: 100))
firstShape.addLine(to: CGPoint(x: 150, y: 170))
firstShape.addLine(to: CGPoint(x: 100, y: 150))
firstShape.close()
let secondShape = UIBezierPath(rect: CGRect(x: 125, y: 125, width: 75, height: 75))
let combined = UIBezierPath()
combined.append(firstShape)
combined.append(secondShape)
combined.usesEvenOddFillRule = false
UIColor.black.setFill()
combined.fill()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With