将视图控制器弹出到不存在的视图控制器

Posted

技术标签:

【中文标题】将视图控制器弹出到不存在的视图控制器【英文标题】:Pop the view controller to a non-existent view controller 【发布时间】:2015-11-29 16:54:32 【问题描述】:

我有一个具有 LoginViewController 和 DashboardViewController 的应用程序。如果用户成功登录,他/她将被带到 DashboardViewController。

LoginViewController 有一个记住我 选项。如果用户在登录时勾选它,该值将存储在 NSUserDefaults 中以用于后续登录。例如,如果用户在登录时打开了记住我选项,那么下次用户打开应用程序时,他/她会直接被带到 DashboardViewController 而不会显示 LoginViewController。

这是我的故事板结构。

在 AppDelegate 中,我根据保存的 NSUserDefaults 值设置窗口的 rootViewController。

if !NSUserDefaults.standardUserDefaults().boolForKey(Globals.IsLoggedIn) 
    // Show login screen
    let loginViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("LoginViewController")
    let navigationController = UINavigationController(rootViewController: loginViewController)
    window?.rootViewController = navigationController
 else 
    // Show Dashboard
    let dashboardViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateInitialViewController()!
    let navigationController = UINavigationController(rootViewController: dashboardViewController)
    window?.rootViewController = navigationController

一切都很好。问题是当我必须退出时。

在 DashboardViewController 的导航栏中,有一个 UIBarButtonItem 可以在点击并确认时将您注销。

let alert = UIAlertController(title: "Logout", message: "Are you sure you want to logout?", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Yes", style: .Default, handler:  (action) -> Void in
    NSUserDefaults.standardUserDefaults().setBool(false, forKey: Globals.IsLoggedIn)
    self.navigationController?.popViewControllerAnimated(true)
))
presentViewController(alert, animated: true, completion: nil)

如果用户从 LoginViewController 登录,移动到 DashboardViewController 并注销,DashboardViewController 会从导航堆栈中弹出并出现 LoginViewController。都很好。

但是假设我在之前的登录中打开了“记住我”选项,然后我打开了应用程序。现在我被直接带到了 DashboardViewController。注意嵌入 DashboardViewController 的 navigationController 是如何设置为窗口的 rootViewController 的。

所以,如果我现在退出,就没有可弹回的 LoginViewController 实例,因为它从一开始就没有被添加!

如何解决这种情况?有没有办法秘密地实例化 LoginViewController 的实例,即使直接直接显示 DashboardViewController,但默默地将其添加到导航堆栈,但仍将 DashboardViewController 显示为第一个视图控制器或其他什么?

或者你会推荐一种不同的方法,整体架构?

【问题讨论】:

【参考方案1】:

试试这个:

let vc = self.storyboard?.instantiateViewControllerWithIdentifier("LoginViewController")
self.navigationController?.viewControllers.insert(vc!, atIndex: 0) // at the beginning
self.navigationController?.popViewControllerAnimated(true)

【讨论】:

这是一个巧妙的技巧。我modified我的代码基于您的解决方案,它运行良好。谢谢。 是的,当您学习如何使用可用工具时感觉很好。

以上是关于将视图控制器弹出到不存在的视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

弹出到初始视图控制器

将带有可见导航栏的视图控制器弹出到带有隐藏导航栏的视图控制器时,带有 interactivePopGestureRecognizer 的黑色区域

不会从子视图控制器弹出到父视图

我应该如何弹出到特定的视图控制器?

从模态弹出到根视图控制器

当标签栏点击两次时禁用自动弹出到根视图控制器