I have added mask in a overlay to create a spotlight effect in SwiftUI. But at the same time I want the user to interact with the view through that window opening that I have such as sliding a slider or tapping a button while totally block other interactions.
The problem I'm facing is that I'm not able to make interaction through this mask window because it's an overlay. Is there a way I could enable interaction only in the white highlighted area ?
This is how it looks
This is my code to achieve the overlay with highlighted window(spotlight)
ZStack {
VStack {
Slider(
value: $speed,
in: 0...100,
onEditingChanged: { editing in
isEditing = editing
}
)
Text("\(speed)")
.foregroundColor(isEditing ? .red : .blue)
}
.padding(.top, 100)
Rectangle()
.fill(Color.black.opacity(0.5))
.mask {
Rectangle()
.overlay(alignment: .topLeading) {
let rect = CGRect(x: 0, y: 500, width:390, height: 80)
RoundedRectangle(cornerRadius: 10, style: .continuous)
.frame(width: rect.width, height: rect.height)
.offset(y:90)
.blendMode(.destinationOut)
}
}
}
So I finally found a solution. Instead of doing mask. What I did is use path and make that clipped so that user can interact through clear pixels. Thanks to this answer here.
func HoleShapeMask(in rect: CGRect) -> Path {
var shape = Rectangle().path(in: rect)
shape.addPath(Circle().path(in: rect))
return shape
}
struct TestInvertedMask: View {
let rect = CGRect(x: 0, y: 0, width: 300, height: 100)
var body: some View {
Rectangle()
.fill(Color.blue)
.frame(width: rect.width, height: rect.height)
.mask(HoleShapeMask(in: rect)
.fill(style: FillStyle(eoFill:true)))
}
}