如何从另一个 class 执行 popViewController?
How to do popViewController from another class?
我的应用有一个 TabBarController。每个 tabBarItem 都与嵌入在 NavigationController 中的 ViewController 相关。
在第一个 tabBarItem 中选择另一个 tabBarItem 时,我想在移动到所选 ViewController 之前做一些事情。因此,我为我的 tabBarController 创建了一个 class 并将其设为 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 时,我们离开该项目时 'active' 相同的 viewController 仍然显示。
我检查了我想要弹出的 viewController 实际上在导航堆栈中并且 navContr != nil.
我错过了什么?
你没有这么说,但我假设你传递给警报视图控制器的 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 {}
应该可以。
我的应用有一个 TabBarController。每个 tabBarItem 都与嵌入在 NavigationController 中的 ViewController 相关。
在第一个 tabBarItem 中选择另一个 tabBarItem 时,我想在移动到所选 ViewController 之前做一些事情。因此,我为我的 tabBarController 创建了一个 class 并将其设为 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 时,我们离开该项目时 'active' 相同的 viewController 仍然显示。
我检查了我想要弹出的 viewController 实际上在导航堆栈中并且 navContr != nil.
我错过了什么?
你没有这么说,但我假设你传递给警报视图控制器的 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 {}
应该可以。