我继承了我要彻底解决的现有应用程序中的导航控制器问题。
此应用程序具有多个情节提要和多个UINavigationControllers。在应用程序中的某个时刻,使用单独的情节提要板和单独的导航控制器以模态方式显示了一系列视图控制器。模态过程完成后,导航层次结构如下所示:
NavController1 -> VC1 ['Present Modally'segue]-> NavController2 -> VC2 -> VC3 -> VC4
当用户完成VC4中的模式活动时,将在VC4上以编程方式调用dismiss(),然后用户可以使用“后退”按钮导航回VC1。
但是,我们真正需要做的是当用户完成模态活动时“弹出”所有模态呈现的视图控制器(及其导航控制器)。问题是从VC3或VC4,我无法调用popToRootViewController()。由于当前的Nav控制器无法管理VC1,因此我也无法遍历VC堆栈来找到VC1。
想到几个解决方案:
1)使用通知管理器,并让VC1监听消息以将所有内容弹回到自己身上
2)将对VC1的引用作为委托一直传递到整个链上,以便VC3或VC3可以使所有内容都消失
这两种解决方案都遵循普遍的原则,即提出的VC应该是被驳回的VC,但我认为这也不是干净的。
我欢迎任何想法或替代解决方案。
答案 0 :(得分:0)
假设这些是视图控制器的布局方式:
NavController1-['Root View Controller'segue]-> VC1-['Present Modally'segue]-
-> NavController2-['Root View Controller'segue]-> VC2-['Push'segue]-> VC3-['Push'segue]-> VC4
您应该可以通过关闭VC2,VC3或VC4来返回VC1。
// example for vc4
vc4.navigationController?.dismiss(animated: true, completion: nil)
但是,如果每个viewController都是模态显示的,则您应该能够遍历presentingViewController
到达VC1。
var currentVC: UIViewController? = self
var presentingVC: UIViewController? = currentVC?.presentingViewController
while presentingVC != nil && !(presentingVC is VC1) {
currentVC?.dismiss(animated: true, completion: nil)
currentVC = presentingVC
presentingVC = currentVC?.presentingViewController
}
希望有帮助。
答案 1 :(得分:0)
弹出时,您可以从导航控制器中踢出viewControllers,可以解决您的问题
extension UINavigationController {
public func removeViewController(classes : [String]) {
var vcs = [UIViewControllers]()
for viewController in self.viewControllers {
let name = viewController.className
if !classes.contains(name) {
vcs.append(viewController)
}
}
if classes.count < vcs.count {
self.viewControllers = vcs
}
}
}
现在认为您有4个viewControllers,A,B,C,D,您想要删除B和C并移回A
在D的视图控制器中
override func viewDidLoad() {
super.viewDidLoad()
//your works
let viewControllersToRemove = [String(describing: type(of:B)), String(describing: type(of:C))]
navigationController.removeViewControoler(classes : viewControllersToRemove)
}