onTapGesture conflicts with button

I want to perform some code when the form is tapped. However the button in the form is affected by the onTapGesture either. I want the button tapped to execute the action block, not the onTapGesture block. How should I do? Thanks in advance.

struct TextFieldPopupView: View {
    @State private var text = ""
    @State private var isON = false

    var body: some View {
        Form{
            Text("Hello")
            TextField("Hello", text: $text)
 .textFieldStyle(RoundedBorderTextFieldStyle())
            Button(action: {
                print("Button")
            }, label: {Text("Button")})
            Toggle(isOn: $isON, label: {
                Text("Toggle")
            })
        }
        .onTapGesture {
            print("Form")
        }
    }
}
Answered by workingdogintokyo in 677448022

here are a few ideas. Since you also have the ".onTapGesture" on the Form itself, it will also be called. So you will have to use some flag to determine which is being called.

struct TextFieldPopupView: View {
    @State private var text = ""
    @State private var isON = false

    var body: some View {
        Form {
            Text("Hello")
            TextField("Hello", text: $text).textFieldStyle(RoundedBorderTextFieldStyle())

            Button("Button1"){
                print("Button1")
            }.buttonStyle(BorderlessButtonStyle())

            Text("Button2").foregroundColor(.blue)
                .onTapGesture {
                    print("Button2")
                }

            Button("Button3"){}
                .onTapGesture {
                    print("Button3")
                }

            Toggle(isOn: $isON, label: {
                Text("Toggle")
            })
        }
        .onTapGesture {
            print("---> Form")
        }
    }

}
Accepted Answer

here are a few ideas. Since you also have the ".onTapGesture" on the Form itself, it will also be called. So you will have to use some flag to determine which is being called.

struct TextFieldPopupView: View {
    @State private var text = ""
    @State private var isON = false

    var body: some View {
        Form {
            Text("Hello")
            TextField("Hello", text: $text).textFieldStyle(RoundedBorderTextFieldStyle())

            Button("Button1"){
                print("Button1")
            }.buttonStyle(BorderlessButtonStyle())

            Text("Button2").foregroundColor(.blue)
                .onTapGesture {
                    print("Button2")
                }

            Button("Button3"){}
                .onTapGesture {
                    print("Button3")
                }

            Toggle(isOn: $isON, label: {
                Text("Toggle")
            })
        }
        .onTapGesture {
            print("---> Form")
        }
    }

}

you could try something like this:

struct TextFieldPopupView: View {
    @State private var text = ""
    @State private var isON = false
    @State var buttonTap = false

    var body: some View {
        Form {
            Text("Hello")
            TextField("Hello", text: $text).textFieldStyle(RoundedBorderTextFieldStyle())

            Button("Button"){
                buttonTap = true
                print("Button")
            }.buttonStyle(BorderlessButtonStyle())
            .border(Color.red)

            Toggle(isOn: $isON, label: {
                Text("Toggle")
            })
        }.buttonStyle(BorderlessButtonStyle())
        .onTapGesture {
                if buttonTap {
                    // just reset the button tap flag
                    buttonTap = false
                } else {
                    print("---> Form only tapped")
                    // do Form tap only
                }
            }
    }
}
onTapGesture conflicts with button
 
 
Q