问题描述
我正在尝试在用户注销后将rootview控制器更改为其他屏幕。
if let window = UIApplication.shared.windows.first {
window.rootViewController = UIHostingController(rootView: SignInView())
window.endEditing(true)
window.makeKeyAndVisible()
}
这是我到目前为止所拥有的。它导航到其他视图,但是使新的新视图上的按钮不可用。有没有更好的方法来更改rootview或我缺少什么?
解决方法
我的方法是创建一个可观察的对象,以协调各种应用程序视图之间的导航。下面是一个简化的示例,可为您提供一个想法:
//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)
}
}
}
}
请注意,您可以将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()
}
要在MainAppView
和LoginView
之间切换,您只需修改environmentObject showingView
的值
self.showingView.viewId = AppViews.LoginView
我希望它可以指导您正确的方向
,如果您在项目中使用 SceneDelegate.swift 文件,请尝试这种方式。
func scene(_ scene: UIScene,willConnectTo session: UISceneSession,options connectionOptions: UIScene.ConnectionOptions) {
guard let scene = (scene as? UIWindowScene) else { return }
// Instantiate UIWindow with scene
let window = UIWindow(windowScene: scene)
// Assign window to SceneDelegate window property
self.window = window
// Set initial view controller from Your storyboard as root view controller of UIWindow
self.window?.rootViewController = UIStoryboard(name: "Your StoryBoard Name",bundle: nil).instantiateInitialViewController()
// Present window to screen
self.window?.makeKeyAndVisible()
}
如果您不使用 ScanDelegate.swift ,请使用 AppDelegate.swift ,然后尝试这种方式。
没有InitalViewController:
func logOut {
let storyboard = UIStoryboard(name: "Your StoryBoard",bundle: nil)
if let navigationController = storyboard.instantiateInitialViewController() as? UINavigationController,let loginvc = storyboard.instantiateViewController(withIdentifier: "Your Selected ViewController") as? YourSelectedViewController {
navigationController.viewControllers = [loginvc]
AppDelegate.getAppDelegate().window?.rootViewController = navigationController
}
}
使用InitalViewController:
func logOut() {
let storyboard = UIStoryboard(name: "Your StoryBoard",bundle: nil)
let navigationController = storyboard.instantiateInitialViewController()
AppDelegate.getAppDelegate().window?.rootViewController = navigationController
}
扩展名:
extension AppDelegate {
class func getAppDelegate() -> AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
}