I'm trying to add a mask to two shapes such that the second shape masks out the first shape. If I do something like Circle().mask(Circle().offset(…))
, this has the opposite affect: preventing anything outside the first circle from being visible.
For UIView
the answer is here: iOS invert mask in drawRect
However, trying to implement this in SwiftUI without UIView
eludes me. I tried implementing an InvertedShape with I could then use as a mask:
struct InvertedShape<OriginalType: Shape>: Shape {
let originalShape: OriginalType
func path(in rect: CGRect) -> Path {
let mutableOriginal = originalShape.path(in: rect).cgPath.mutableCopy()!
mutableOriginal.addPath(Path(rect).cgPath)
return Path(mutableOriginal)
.evenOddFillRule()
}
}
Unfortunately, SwiftUI paths do not have addPath(Path)
(because they are immutable) or evenOddFillRule()
. You can access the path's CGPath and make a mutable copy and then add the two paths, however, evenOddFillRule
needs to be set on the CGLayer
, not the CGPath
. So unless I can get to the CGLayer, I'm unsure how to proceed.
This is Swift 5.
Path
s don't have fill rules, butShape
s do. – Clasp.fill
returns a view, not a path... So that was a problem with my implementation, because I kinda wanted to return a path or shape... But that was not really needed, I just thought it was. – Clasp