简体   繁体   中英

SwiftUI Change View with Button

I understand there is PresentationButton and NavigationButton in order to change views in the latest SwiftUI. However I want to do a simple operation like below. When user clicks on SignIn button if credentials are correct it will sign them in but also do a segue (in this case change the view). However I could not check if they are correct in PresentationButton and I could not change the view in a normal button. Is there another way to do that?

  @IBAction func signInClicked(_ sender: Any) {

        if emailText.text != "" && passwordText.text != "" {

            Auth.auth().signIn(withEmail: emailText.text!, password: passwordText.text!) { (userdata, error) in
                if error != nil {
                   //error
                } else {

                   performSegue(withIdentifier: "toFeedActivity", sender: nil)


                }
            }

        } else {
            //error
        }




    }

Here's one way.

struct AppContentView: View {
    
    @State var signInSuccess = false
    
    var body: some View {
        return Group {
            if signInSuccess {
                AppHome()
            }
            else {
                LoginFormView(signInSuccess: $signInSuccess)
            }
        }
    }
}

struct LoginFormView : View {
    
    @State private var userName: String = ""
    @State private var password: String = ""
    
    @State private var showError = false
    
    @Binding var signInSuccess: Bool
    
    var body: some View {
        VStack {
            HStack {
                Text("User name")
                TextField("type here", text: $userName)
            }.padding()
            
            HStack {
                Text(" Password")
                TextField("type here", text: $password)
                    .textContentType(.password)
            }.padding()
            
            Button(action: {
                // Your auth logic
                if(self.userName == self.password) {
                    self.signInSuccess = true
                }
                else {
                    self.showError = true
                }
                
            }) {
                Text("Sign in")
            }
            
            if showError {
                Text("Incorrect username/password").foregroundColor(Color.red)
            }
        }
    }
}

struct AppHome: View {
    
    var body: some View {
        VStack {
        Text("Hello freaky world!")
        Text("You are signed in.")
        }
    }
}

I had the same need in one of my app and I've found a solution...

Basically you need to insert your main view in a NavigationView, then add an invisible NavigationLink in you view, create a @state var that controls when you want to push the view and change it's value on your login callback...

That's the code:

struct ContentView: View {
    @State var showView = false
    var body: some View {
        NavigationView {
            VStack {
                Button(action: {
                    print("*** Login in progress... ***")
                    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                        self.showView = true
                    }
                }) {
                    Text("Push me and go on")
                }

                //MARK: - NAVIGATION LINKS
                NavigationLink(destination: PushedView(), isActive: $showView) {
                    EmptyView()
                }
            }
        }
    }
}


struct PushedView: View {
    var body: some View {
        Text("This is your pushed view...")
            .font(.largeTitle)
            .fontWeight(.heavy)
    }
}

Try with state & .sheet

struct ContentView: View {
    @State var showingDetail = false

    var body: some View {
        Button(action: {
            self.showingDetail.toggle()
        }) {
            Text("Show Detail")
        }.sheet(isPresented: $showingDetail) {
            DetailView()
        }
    }
}

You can use navigation link with tags so,

Here is the code:

first of all, declare tag var

@State var tag : Int? = nil

then create your button view:

Button("Log In", action: {
                        Auth.auth().signIn(withEmail: self.email, password: self.password, completion: { (user, error) in
                            if error == nil {
                                self.tag = 1
                                print("success")
                            }else{
                                print(error!.localizedDescription)
                            }
                        })

So when log in success tag will become 1 and when tag will become 1 your navigation link will get executed

Navigation Link code:

NavigationLink(destination: HomeView(), tag: 1, selection: $tag) {
                EmptyView()
                }.disabled(true)

if you are using Form use .disabled because here the empty view will be visible on form and you don't want your user to click on it and go to the homeView.

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