Best approach to optionally show sign-up view, with SwiftUI?

Hi,


I need logic like this, using SwiftUI:


if userHasAccount {
    showDashboardView()
}
else {
    showSignupView() // blocks progress until complete
    showDashboardView()
}


I'm unsure where/how the best place and approach for this is.


My instincts say that the scene() method in SceneDelegate would be the place to conditionally alter the rootView. But then how do I, on signup completion, disgard the signup root view and transition to the dashboard view?


I've read quite a few approaches to conditional views implement AnyView casting or using Group, within the default contentView. This seems a little bit of a hack?


thanks,

Accepted Reply

You can write something like this:

class UserStatus: ObservableObject {
    @Published var hasAccount: Bool = false
    
    //...
}

struct ContentView: View {
    @EnvironmentObject var userStatus: UserStatus
    
    var body: some View {
        ZStack {
            DashboardView()
            if !userStatus.hasAccount {
                SignupView()
                    //Add effects as you like...
                    //.transition(.move(edge: .bottom))
                    //.animation(.easeOut)
            }
        }
    }
}


Make this ContentView the root view of your app, and SignupView cover the whole screen, User will see SignupView if not hasAccount.

And set hasAccount to true, when user finishes signup.

Replies

Ahh, cool. Thanks.


For anyone else, here's this method with a navigation view.


struct ContentView: View {
   
    @EnvironmentObject var userStatus: UserStatus
   
    var body: some View {
        ZStack {
            NavigationView {
                NavigationLink(destination: Text("Second View")) {
                    Text("Hello, World!")
                }
                .navigationBarTitle("Navigation")
            }
           
            if !userStatus.hasAccount {
                Text("test: has no account")
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                .background(Color.red)
                .edgesIgnoringSafeArea(.all)
            }
        }
    }
}

class UserStatus: ObservableObject {
    @Published var hasAccount: Bool = true
   
    //...
}


And with a tab view (which I'm using):


struct ContentView: View {
   
    @EnvironmentObject var userStatus: UserStatus
   
    var body: some View {
        ZStack {
            TabView {
                Text("First View")
                    .tabItem {
                        Image(systemName: "1.circle")
                        Text("First")
                    }.tag(0)
            }
           
            if !userStatus.hasAccount {
                Text("test: has no account")
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                .background(Color.red)
                .edgesIgnoringSafeArea(.all)
            }
        }
    }
}

class UserStatus: ObservableObject {
    @Published var hasAccount: Bool = false
   
    //...
}
That's essentially what I've been doing. ZStack with the primary view as the first child and conditionally showing the sign up view over it. Seems to have worked well so far.