0

So I've made a Button view in my body and I have set it's action to a Google Sign In action, but I want it to also transition to a new view when the sign in flow is completed. The problem is that I have set the label of the button to a Navigation Link and when I click it, it directly transitions to a next view. How can I delay the transition? For context, VoucherView is the next view I want to transition to.

Button {
                    guard let clientID = FirebaseApp.app()?.options.clientID else { return }
                    
                    // Create Google Sign In configuration object.
                    let config = GIDConfiguration(clientID: clientID, serverClientID: GlobalConstants.BACKEND_SERVER_REQUEST_ID_TOKEN)
                    
                    guard let presenter = CommonHelper.GetRootViewController() else {return}
                    
                    // Start the sign in flow!
                    GIDSignIn.sharedInstance.signIn(with: config, presenting: presenter) {user, error in
                        
                        if let error = error {
                            print (error.localizedDescription)
                            return
                        }
                        
                        guard
                            let authentication = user?.authentication,
                            let idToken = authentication.idToken
                        else {
                            print ("Something went wrong!")
                            return
                        }
                        
                        print (authentication)
                        print (idToken)
                        
                        let credential = GoogleAuthProvider.credential(withIDToken: idToken,
                                                                       accessToken: authentication.accessToken)
                        print (credential)
                        UserManager.shared.firebaseAuthentication(credential: credential)
                        signed = true
                        
                    }
                } label: {
                    NavigationLink {
                        
                        VoucherView()
                        
                    } label: {
                        Text("Sign In")
                    }

                }

Edit: After I tried using isValid as a @State variable, after every cycle of SignIn and SignOut the screen goes down.

First SignIn

FirstSignOut

SecondSignIn

SecondSignOut

1 Answer 1

0

Instead of using NavigationLink inside your Button, you can use a NavigationLink with an EmptyView for a label and then activate it programmatically with the isActive parameter.

See the following example -- the Google Sign In process is replaced by just a simple async closure for brevity.

struct ContentView: View {
    @State private var navigateToNextView = false
    
    var body: some View {
        NavigationView {
            VStack {
                Button {
                    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                        navigateToNextView = true
                    }
                } label: {
                    Text("Sign in")
                }
                NavigationLink(destination: View2(), isActive: $navigateToNextView) { EmptyView()
                }
            }
        }.navigationTitle("Test")
    }
}

struct View2 : View {
    var body: some View {
        Text("Next view")
    }
}

A couple more notes:

  • Note that there has to be a NavigationView (make sure it's just one) in the hierarchy for this to work
  • In general, async work is better done in an ObservableObject than in a View. You can consider moving your login function to an ObservableObject and making the navigateToNextView a @Published property on that object.
Sign up to request clarification or add additional context in comments.

15 Comments

Your method worked pretty good, except there is a little problem. Every time I go back from the second to the first view and back, the second view moves down a little bit, which is a very strange behaviour.
I'm not seeing that with my code. Are you sure that you're testing just the code I presented with no modifications? It sounds like a symptom of having multiple NavigationViews in your hierarchy.
Yeah the code is one to one, there is only one NavigationView, there are two files and that's it.
What version of iOS?
iOS 15.0, can it be related?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.