swiftuinavigationlinkxcode12

SwiftUI NavigationLink not behaving correctly when buttons are close together


I'm trying to implement a programmable NavigationLink to go to another view, triggered by a simple button. But when that button is next to another button, instead of triggering the NavigationLink, it triggers the action of the button next to it.

struct NavLinkView: View {
    @State var showPasswordStr = true
    @State var showCheckView = false
    @State var password = "Abc"
    var body: some View {
        Form {
            VStack {
                NavigationLink(destination: CheckView(), isActive: $showCheckView ) {
                    EmptyView()
                }
                Text("Password")
                    .font(.system(size: 12, weight: .light, design: .default))
                    .foregroundColor(.gray)
                HStack {
                    
                    if showPasswordStr {
                        TextField("", text: $password)
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                    } else {
                        SecureField("", text: $password)
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                    }
                    Button(action: {
                        showPasswordStr.toggle()
                    } ) {
                        Image(systemName: showPasswordStr ? "eye.slash" : "eye" )
                    }
                    .padding(.leading)

                    Button(action: { showCheckView.toggle() } ) {
                        Image(systemName: "checkmark.circle" )
                    }
                    .padding(.leading)
                }
            }
        }
    }
}

What am I mising? If I move the NavigationLink to be after the VStack, then both buttons trigger both the action of the first button and the NavigationLink.


Solution

  • As your buttons are in a Form you need to change their style to PlainButtonStyle:

    Button(action: {
        self.showPasswordStr.toggle()
    }) {
        Image(systemName: showPasswordStr ? "eye.slash" : "eye")
    }
    .buttonStyle(PlainButtonStyle()) // <- add style
    
    Button(action: { self.showCheckView.toggle() }) {
        Image(systemName: "checkmark.circle")
    }
    .buttonStyle(PlainButtonStyle()) // <- add style