Search code examples
swiftswiftuiios13xcode11swift5

swiftui textfiled and button inside a button


I am trying to trigger button when a user clicks background area of a view. As a solution, I decided to make a button and put the view into the button as a label. But the Problem is that the button is triggered even on the TextField and sometimes on another button inside.

How can i disable the back button on some views (TextField and Button in this case) I select?

I attach my code below and rendered preview.

import SwiftUI

struct ButtonOnbutton: View {
    @State var memo: String = ""
    var body: some View {
        Button(action: {
            print("down button clicked")
        }) {
            VStack(spacing: 10) {
                Text("before")
                    .foregroundColor(.white)
                TextField("type memo", text: $memo)
                    .font(.custom("SFProDisplay-Regular", size: 12))
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                Text("after")
                    .foregroundColor(.white)
                Button(action: {
                    print("inside button clicked")
                }) {
                    Text("inside button")
                        .foregroundColor(.white)
                }
                .background(Color.red)
            }
        }
        .background(Color.blue)
    .padding()
    }
}

struct buttonOnbutton_Previews: PreviewProvider {
    static var previews: some View {
        ButtonOnbutton()
    }
}

Solution

  • If I correctly understood your goal then it is better to used onTapGesture instead of button, as shown below

    var body: some View {
        VStack(spacing: 10) {
            Text("before")
                .foregroundColor(.white)
            TextField("type memo", text: $memo)
                .font(.custom("SFProDisplay-Regular", size: 12))
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .onTapGesture {} // << just blocks outer tap
            Text("after")
                .foregroundColor(.white)
            Button(action: {
                print("inside button clicked")
            }) {
                Text("inside button")
                    .foregroundColor(.white)
            }
            .background(Color.red)
        }
        .background(Color.blue)
        .onTapGesture {
            print("background area clicked")
        }
        .padding()
    }