Search code examples
iosswiftuser-interfaceviewswiftui

How do I refresh View in SwiftUI


I have an app with log in screen. It has to 3 tabs. Once the app loads it loads a log in tab. But once the credentials are hit and the if statement turns to true it doesn't show the other tabs. I would like to know how to refresh the view once the conditional turns to true.

ViewConsole

import SwiftUI

var verify = false

struct ViewConsole: View {
    var body: some View {
        if verify == true {
            TabView{
                ContentView()
                    .tabItem {
                        Label("Names", systemImage: "person.3")
                    }
                
                AdminView()
                    .tabItem{
                        Label("Admin", systemImage: "gear")
                    }
            }
        } else {
            LoginView()
                .tabItem{
                    Label("Log In", systemImage: "key")
                }
        }
    }
}

struct ViewConsole_Previews: PreviewProvider {
    static var previews: some View {
        ViewConsole()
            .environmentObject(Admin())
    }
}

App Delegate

import SwiftUI

@main
struct Work_Tracker_For_KumonApp: App {
    @StateObject var admin = Admin()
    
    var body: some Scene {
        WindowGroup {

            ViewConsole()
                .environmentObject(admin)
        }
    }
}

Solution

  • You aren't going to want verify to be a global variable. One way to do it would be to add a @State property to your ViewConsole. To have access to it in your LoginView, you can pass a Binding to it using the $ symbol.

    struct ViewConsole: View {
        @State private var verify = false
        
        var body: some View {
            if verify {
                TabView {
                    Text("Content")
                        .tabItem {
                            Label("Names", systemImage:
                                    "person.3")
                        }
                    Text("Admin")
                        .tabItem{
                            Label("Admin", systemImage:
                                    "gear")
                        }
                }
            } else {
                LoginView(verify: $verify)
                    .tabItem{
                        Label("Log In", systemImage:
                                "key")
                    }
            }
            
        }
    }
    
    struct LoginView : View {
        @Binding var verify : Bool
        
        var body: some View {
            Button(action: {
                verify = true
            }) {
                Text("Verify")
            }
        }
    }
    
    

    A second way to approach this would be to use an ObservableObject with a @Published property. It looks like you already have one called Admin set up as a environmentObject. It might look something like this:

    class Admin : ObservableObject {
        @Published var loggedIn = false
    }
    
    struct ViewConsole: View {
        @EnvironmentObject var admin : Admin
        
        var body: some View {
            if admin.loggedIn {
                TabView {
                    Text("Content")
                        .tabItem {
                            Label("Names", systemImage:
                                    "person.3")
                        }
                    Text("Admin")
                        .tabItem{
                            Label("Admin", systemImage:
                                    "gear")
                        }
                }
            } else {
                LoginView()
                    .tabItem{
                        Label("Log In", systemImage:
                                "key")
                    }
            }
            
        }
    }
    
    struct LoginView : View {
        @EnvironmentObject var admin : Admin
    
        var body: some View {
            Button(action: {
                admin.loggedIn = true
            }) {
                Text("Verify")
            }
        }
    }