Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
        }
    }
like image 990
Atils Avatar asked Jun 27 '19 19:06

Atils


People also ask

How do I switch between views in Xcode?

From the Library, add a button to the first View Controller and name the button, for example: Show Second View . Select the button, press and hold the Control key on the keyboard and drag from the button to the second View Controller.

What is NavigationView?

↳ com.google.android.material.navigation.NavigationView. Represents a standard navigation menu for application. The menu contents can be populated by a menu resource file. NavigationView is typically placed inside a DrawerLayout .

How do I navigate from one view to another view in SwiftUI?

If you have a navigation view and you want to push a new view onto SwiftUI's navigation stack, you should use NavigationLink .


2 Answers

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.")
        }
    }
}

like image 194
Sada Avatar answered Sep 21 '22 14:09

Sada


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)
    }
}
like image 41
DungeonDev Avatar answered Sep 23 '22 14:09

DungeonDev