Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI 2 pop to root view with no Scene delegate

Tags:

swift

swiftui

I would like to refresh root view when user logs out but I can’t find how to do it under the new Scene-less SwiftUi 2.

Next is @Swissmark posted solution I'm trying to implement in SwiftUI 2:

let contentView = AppRootView(showingView: ShowingView(showingView: appStartView))

if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = UIHostingController(rootView: contentView)
    self.window = window
    window.makeKeyAndVisible()
}
like image 742
Matias Masso Avatar asked Jan 19 '21 22:01

Matias Masso


1 Answers

A possible solution is to create an ObservableObject that is responsible for routing:

enum AppView {
    case login, main
}

class ViewRouter: ObservableObject {
    // here you can decide which view to show at launch
    @Published var currentView: AppView = .login
}

Then, you can inject this ViewRouter as an EnvironmentObject to the root view:

@main
struct TestApp: App {
    @StateObject private var viewRouter = ViewRouter()
    
    var body: some Scene {
        WindowGroup {
            RootView()
                .environmentObject(viewRouter)
        }
    }
}

Now you can change the current view from any view:

struct RootView: View {
    @EnvironmentObject private var viewRouter: ViewRouter
    
    var body: some View {
        VStack {
            if viewRouter.currentView == .login {
                LoginView()
            } else if viewRouter.currentView == .main {
                MainView()
            }
        }
    }
}

struct LoginView: View {
    @EnvironmentObject private var viewRouter: ViewRouter
    
    var body: some View {
        VStack {
            Text("Login View")
            Button("Log in") {
                viewRouter.currentView = .main
            }
        }
    }
}

struct MainView: View {
    @EnvironmentObject private var viewRouter: ViewRouter
    
    var body: some View {
        VStack {
            Text("Main View")
            Button("Log out") {
                viewRouter.currentView = .login
            }
        }
    }
}
like image 67
pawello2222 Avatar answered Oct 18 '22 04:10

pawello2222