How to push a new root view using SwiftUI without NavigationLink?

后端 未结 2 1754
你的背包
你的背包 2020-12-17 06:40

I have a login screen. After user fill up credential, I want to verify it then start a new root view so user won\'t be able to navigate back to the login view. I currently

相关标签:
2条回答
  • 2020-12-17 07:13

    Here is possible alternate approach of how to replace root view completely... using notifications

    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        let loginRootViewNotification = 
             NSNotification.Name("loginRootViewNotification") // declare notification
        private var observer: Any?               // ... and observer
    
    
        ...
        // in place of window creation ...
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
    
            observer = NotificationCenter.default.addObserver(forName: loginRootViewNotification, object: nil, queue: nil, using: { _ in
                let anotherRootView = AnotherRootView() 
                // create another view on notification and replace
                window.rootViewController = UIHostingController(rootView: anotherRootView)
            })
    

    in your desired place post needed notification

    Button(action: { 
    // launch new root view here 
       NotificationCenter.default.post(loginRootViewNotification)
    }, label: {Text("Login")}).padding()
    
    0 讨论(0)
  • 2020-12-17 07:26

    Another approach with Notifications is to place the observer inside your RootView and check for changes in a variable to decide which View should be presented, here is a very simplified example:

    struct RootView: View {
    
        @State var isLoggedIn: Bool = false
    
        var body: some View {
            Group {
                VStack{
                    if isLoggedIn {
                        Text("View B")
                        Button(action: {
                            NotificationCenter.default.post(name: NSNotification.Name("changeLogin"), object: nil)
                        }) {
                            Text("Logout")
                        }
                    } else {
                        Text("View A")
                        Button(action: {
                            NotificationCenter.default.post(name: NSNotification.Name("changeLogin"), object: nil)
                        }) {
                            Text("Login")
                        }
                    }
                }
            }.onAppear {
                NotificationCenter.default.addObserver(forName: NSNotification.Name("changeLogin"), object: nil, queue: .main) { (_) in
                    self.isLoggedIn.toggle()
                }
            }
        }
    

    And load RootView in your rootViewController as usual.

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        let contentView = RootView()
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
    
    0 讨论(0)
提交回复
热议问题