I need to get only the outline of the union of four circles. That is, a shape with the shape's border.
SwiftUI has .union, but I can't use it within a shape.
struct LeafCloverShape: Shape {
func path(in rect: CGRect) -> Path {
let dimension = min(rect.width, rect.height)
let r = dimension / 4
let center = CGPoint(x: rect.midX, y: rect.midY)
let centers = [
CGPoint(x: center.x - r, y: center.y), // Left
CGPoint(x: center.x + r, y: center.y), // Right
CGPoint(x: center.x, y: center.y - r), // Top
CGPoint(x: center.x, y: center.y + r) // Bottom
]
let cgPath = CGMutablePath()
for c in centers {
cgPath.addEllipse(in: CGRect(x: c.x - r, y: c.y - r, width: r * 2, height: r * 2))
}
return Path(cgPath)
}
}
#Preview {
LeafCloverShape()
.stroke(.green, lineWidth: 4)
.frame(width: 256, height: 256)
}
There is a union
function on both CGPath
(CGPath.union
) and SwiftUI Path
(Path.union
). Instead of adding a subpath using addEllipse
, call union
instead.
var cgPath: CGPath = CGMutablePath()
for c in centers {
cgPath = cgPath.union(CGPath(ellipseIn: CGRect(x: c.x - r, y: c.y - r, width: r * 2, height: r * 2), transform: nil))
}
return Path(cgPath)
or work with SwiftUI Path
s directly:
return centers.map { c in
Path(ellipseIn: CGRect(x: c.x - r, y: c.y - r, width: r * 2, height: r * 2))
}
.reduce(Path()) { $0.union($1) }