0

我的应用程序有一个 TabBarController。每个 tabBarItem 都与嵌入在 NavigationController 中的 ViewController 相关。

在第一个 tabBarItem 并选择另一个 tabBarItem 时,我想在移动到所选 ViewController 之前做一些事情。因此,我为我的 tabBarController 创建了一个类并将其设为 UITabBarControllerDelegate。

我想要做的是用两个按钮显示一个警报;按钮 A 取消移动到选定的 viewController,按钮 B 让移动发生。

我的问题是,当按下按钮 B 时,我想 popToRootViewController。我给了 navigationController 一个 storyboardID 并尝试实例化它,如下所示。

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    
    if let alert = self.storyboard?.instantiateViewController(withIdentifier: "ActiveSessionWarningAlert") as? ActiveSessionWarningAlert {
            
        alert.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
        alert.modalTransitionStyle = UIModalTransitionStyle.flipHorizontal
            
        let alertWasDismissed: (Bool) -> Void = { userWantsToMoveToSelectedViewController in
                
            if userWantsToMoveToSelectedViewController {
                    
                if let navContr = self.storyboard?.instantiateViewController(withIdentifier: "firstNavContr") as? UINavigationController {
                
                    navContr.popToRootViewController(animated: true)

                }
                    
                tabBarController.selectedViewController = viewController
                    
            
            }
        }
        
        alert.alertWasDismissed = alertWasDismissed
        self.present(alert, animated: true, completion: nil)
        
    }

    return false

}

一切都按预期工作,但 popToRootViewController 似乎没有发生;当再次选择第一个 tabBarItem 时,我们离开该项目时处于“活动”状态的同一 viewController 仍在显示。

我检查了我想要弹出的 viewController 实际上在导航堆栈中,并且 navContr != nil。

我错过了什么?

4

1 回答 1

2

您没有这么说,但我假设alertWasDismissed 您传递给警报视图控制器的闭包在用户关闭警报时被调用。

您关闭的问题是这一点:

if let navContr = self.storyboard?.instantiateViewController(withIdentifier: "firstNavContr") as? UINavigationController 

任何时候您调用instantiateViewController(withIdentifier:),您都在创建一个全新的、从未见过的视图控制器实例(在本例中为导航控制器)。该导航控制器与属于您尝试的当前选项卡的导航控制器无关解雇。除了在故事板中定义的根视图控制器之外,它的导航堆栈中没有任何内容。

您需要做的是在标签栏控制器的tabBarController(_:shouldSelect:)方法中找到当前标签的导航控制器,并将该导航控制器传递给您的alertWasDismissed 闭包。

tabBarController(_:shouldSelect:)调用该方法时,标签栏控制器selectedViewController应该包含当前视图控制器。将上面的行替换为:

if let navContr = tabBarController.selectedViewController? as? UINavigationController {}

应该行得通。

于 2021-01-09T17:01:58.127 回答