繁体   English   中英

如何在没有 NavigationLink 的情况下使用 SwiftUI 推送新的根视图?

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

我有一个登录屏幕。 用户填写凭据后,我想对其进行验证,然后启动一个新的根视图,这样用户将无法导航回登录视图。 我目前有

Button(action: { 
// launch new root view here 
}, label: {Text("Login")}).padding()

我在网上找到的大多数答案都使用了我不想使用的导航链接。 其他一些答案建议通过UIApplication.shared.delegate使用AppDelegate这对我不起作用,因为我有SceneDelegate

这是如何完全替换根视图的可能替代方法...使用通知

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)
        })

在您想要的地方发布需要的通知

Button(action: { 
// launch new root view here 
   NotificationCenter.default.post(loginRootViewNotification)
}, label: {Text("Login")}).padding()

备份

Notifications 的另一种方法是将观察者放置在您的 RootView 中并检查变量中的更改以确定应该显示哪个视图,这是一个非常简化的示例:

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()
            }
        }
    }

并像往常一样在你的 rootViewController 中加载 RootView。

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()
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM