SwiftUI:如何以编程方式更改 rootview 控制器

laz*_*uge 4 ios swift swiftui

我试图在用户注销后将 rootview 控制器更改为不同的屏幕。

    if let window = UIApplication.shared.windows.first {
        window.rootViewController = UIHostingController(rootView: SignInView())
        window.endEditing(true)

        window.makeKeyAndVisible()
    }
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止所拥有的。它导航到不同的视图,但它使新视图上的按钮无法使用。有没有更好的方法来更改 rootview 或者我错过了什么?

小智 8

我的方法是创建一个可观察的对象来协调各个应用程序视图之间的导航。下面一个简化的例子可以给你一个想法:

//Your app views
enum AppViews {
    case LoginView
    case MainAppView
}

//Class that conforms to the ObservableObject protocol and publishes the viewId property.
//Basically your navigation will react to viewId changes

class ShowingView: ObservableObject {
    
    init(showingView: AppViews) {
        self.viewId = showingView
    }
    
    @Published var viewId : AppViews
}

//The current root view of your app is observing changes of the ShowingView class and switch between your app views
struct AppRootView: View {
    
    @ObservedObject var showingView: ShowingView
    
    var body: some View {
        Group {
            if showingView.viewId == .LoginView {
                TermsAndConditionsView()
                    .environmentObject(showingView)
            }
            else {
                MainAppView()
                    .environmentObject(showingView)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,您可以将showingView环境对象传递给视图,并在需要时使用它切换到另一个视图。在您的情况下,当用户注销时切换到另一个屏幕。

场景委托中,您可以在登录视图和主视图之间切换,如下所示

var appStartView: AppViews

let isloggedIn = UserDefaults.standard.bool(forKey: "IsLoggedIn")

if isLoggedIn == false {
    appStartView = .LoginView
}
else {
    appStartView = .MainAppView
}

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()
}
Run Code Online (Sandbox Code Playgroud)

要在 和 之间切换MainAppViewLoginView只需修改environmentObject的值即可showingView

self.showingView.viewId = AppViews.LoginView
Run Code Online (Sandbox Code Playgroud)

我希望它有助于引导您走向正确的方向