0

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

enter image description here

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)
                }
        }
}
Cheolhyun
  • 169
  • 1
  • 7
Asadullah Ali
  • 1,056
  • 14
  • 31

2 Answers2

0

Maybe you can use a combination of the .disabled and .zIndex instead of a mask.

Just a first thought, but it should work.

DADev
  • 1
  • 1
  • I just want a spotlight effect on any existing view and I want to reuse the same spotlight view on any other view. So masking is required to spotlight whichever view the focus is on. – Asadullah Ali Apr 14 '23 at 00:02
0

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)))
    }
}
Asadullah Ali
  • 1,056
  • 14
  • 31