简体   繁体   中英

How to navigate using button with condition check in SwiftUI

Since NavigationButton isn't available anymore, how do I check conditions in NavigationLink in order to navigate to another view?


NavigationLink(destination: Dashboard(userName: self.userId, 
                                      password: self.password), isActive: $showDashboard) {

                    Button(action: {
                        if self.userId.isEmpty || self.password.isEmpty {
                            self.isAlert = true
                        } else {
                            self.showDashboard = true
                        }

                    }) {
                        Text("Submit")
                            .foregroundColor(.white)
                            .font(.system(size: 22))

                        Dashboard()
                    }
                    .frame(minWidth: 150, idealWidth: 300, maxWidth: 450, 
                     minHeight: 30, idealHeight: 40, maxHeight: 50, alignment: .center)
                    .background(Color(red: 81/255, green: 221/255, blue: 182/255))

                    .padding([.leading, .trailing], 20)
                } 

Edit:-

Also I want to show alert if length of userName and password is more then 16 and different alert if length is more than 10 and empty message alert if length is 0.

You can do something like this:

    NavigationView {
        VStack {
            NavigationLink(destination:  Dashboard(userName: self.userId, password: self.password), isActive: $showDashboard) {
                Text("")
            }
            Button(action: {
                 if self.userId.isEmpty || self.password.isEmpty {
                      self.isAlert = true
                  } else {
                      self.showDashboard = true
                  }
            }) {
                Text("Submit")
                    .foregroundColor(.green)
                    .font(.system(size: 22))

            }
        }
    }

A thing to remember is that a NavigationLink is a button itself and when pressed it navigate to the destinationView , the isActive parameter is a way to force that to happen (without the user clicking the NavigationLink). As of now I'm not sure how to embed logic into NavigationLinks.

Hope this helps:)

EDIT:

Another thing you can do is the following:

NavigationLink(destination:Dashboard(userName: self.userId, password: self.password)) {
                    Text("Submit")
                }.disabled(self.userId.isEmpty || self.password.isEmpty )

This would disable the NavigationLink until both input fields are not empty.

I'm not sure if you want to check conditions to determine the destination of the NavigationLink or whether or not it is disabled, but this example code shows how to do both:

struct ContentView: View {
    @State var userId = ""
    @State var password = ""

    var body: some View {
        NavigationView {
            NavigationLink(destination: (self.userId.isEmpty || self.password.isEmpty) ? AnyView(Dashboard(userName: self.userId, password: self.password)) : AnyView(Text("Different view")), isActive: Binding(get: {
                return self.userId.isEmpty || self.password.isEmpty
            }, set: { (_) in

            })) {
                Text("Navigate")
            }
        }
    }
}

Create a custom Binding for isActive to evaluate mulitple conditions:

Binding(get: {
        return self.userId.isEmpty || self.password.isEmpty
}, set: { (_) in

})

And evalute the conditions in a ternary statement , making sure to use AnyView for Type Erasure to return different kinds of views if you want the conditions to determine which view the NavigationLink navigates to:

(self.userId.isEmpty || self.password.isEmpty) ? AnyView(Dashboard(userName: self.userId, password: self.password) : AnyView(Text("Different view"))

Edit : You can set the other view to nil if you do not want the view to transition to anything if the conditional evaluates to false :

(self.userId.isEmpty || self.password.isEmpty) ? AnyView(Dashboard(userName: self.userId, password: self.password) : nil

Edit 2 : If you want an alert to show up when the condition fails, use the above line (with nil ) for the NavigationLink's destination, and add an alert who also has a custom Binding for isPresented :

.alert(isPresented: Binding(get: {
            return self.userId.isEmpty || self.password.isEmpty
    }, set: { (_) in

    })) {
        Text("Alert message")
    }

You can add this alert to any subview in the the view with the variables you are evaluating (in this case, ContentView ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM