首页 > 解决方案 > TabBarController 在调用 popToRootViewController() 后保留他的子控制器

问题描述

我的根视图是一个带有 3 个选项卡的 TabBarController:

    -> TabBarController  -> Tab1 (Login)  -> ViewController
                         -> Tab2          -> NavigationController1 -> ViewController1 (with TextField1) -> ViewController2
                         -> Tab3          -> NavigationController2 -> ViewController3 (with TextField2) -> ViewController4


注销时,我想要:
1.销毁Tab2和Tab3中Textfield1和Textfield2中数据的所有子控制器
2.选择Tab1

我尝试调用 TabBarController 的所有导航控制器的 popToRootViewController(),然后在 TabBarController 中调用 self.selectedIndex = 0。

    fileprivate func popAllNavigationControllersToRoot() {
        if let viewControllers = self.viewControllers {
            for viewController in viewControllers {
                if let navigationController = viewController as? UINavigationController {
                    navigationController.popToRootViewController(animated: false)
                }
            }
        }
    }

    @objc func onDidChangeLoginState(_ notification:Notification) {
        popAllNavigationControllersToRoot()
        self.selectedIndex = 0
    }


这工作正常,但是当我重新登录后

onDidChangeLoginState(..)
并切换到 Tab2 或 Tab3,TextField1/TextField2 包含调用 onDidChangeLoginState(..) 之前的旧值。调用 popToRootViewController 时,ViewController 似乎没有被破坏。我有什么问题吗?

我现在最好的做法是

  LoginScreen -> TabBarController -> Tab1 ...
                                  -> Tab2 ...

但是 Tab1 里面的登录视图是由 PO 设置的。

标签: iosswift

解决方案


  • 除非你告诉它这样做,否则标签栏控制器将保留其视图控制器(ViewController、、NavigationController1NavigationController2。)

  • 除非您告诉他们不这样做,否则两个导航控制器都将保留它们的根视图控制器(ViewController1ViewController3,分别)。

如果您想要这些的新实例,而不是弹出到根目录,您可以重置整个堆栈。例如:

let nav1 = tabBarController.viewControllers[1] as! UINavigationController
let newInstanceOfVC1 = ViewController1() // or initialize from storyboard

nav1.setViewControllers([newInstanceOfVC1], animated: true)

推荐阅读