Search code examples
swiftuigesture

SwuftUI Gesture location detect clicks out of View border


If I put several Views in a row with no spaces (or very little space between them), and attach some Gesture action, I can't correctly detect, which one is tapped. It looks like there is some padding inside gesture that I can't remove.

here's the example code:

struct ContentView: View {
    @State var tap = 0
    @State var lastClick = CGPoint.zero
    var body: some View {
        VStack{
            Text("last tap: \(tap)")
            Text("coordinates: (x: \(Int(lastClick.x)), y: \(Int(lastClick.y)))")
            HStack(spacing: 0){
                ForEach(0...4, id: \.self){ind in
                    RoundedRectangle(cornerRadius: 10)
                        .foregroundColor(Color.gray)
                        .overlay(Text("\(ind)"))
                        .overlay(Circle()
                            .frame(width: 4, height: 4)
                            .foregroundColor(self.tap == ind ? Color.red : Color.clear)
                            .position(self.lastClick)

                        )
                        .frame(width: 40, height: 50)
                        //.border(Color.black, width: 0.5)
                    .gesture(DragGesture(minimumDistance: 0)
                        .onEnded(){value in
                            self.tap = ind
                            self.lastClick = value.startLocation
                        }
                    )
                }
            }
        }
    }
}

and behavior:

enter image description here

I want Gesture to detect 0 button clicked when click location goes negative. Is there a way to do that?


Solution

  • I spent few hours with that problem, and just after I post this question, I found solution. it was so simple - just to add a contentShape modifier

      ...
                           .frame(width: 40, height: 50)
                           .contentShape(Rectangle())
                        .gesture(DragGesture(minimumDistance: 0)
        ...