弹出到 NavigationController 堆栈中的特定 ViewController
Posted
技术标签:
【中文标题】弹出到 NavigationController 堆栈中的特定 ViewController【英文标题】:Popping to specific ViewController in NavigationController stack 【发布时间】:2019-12-04 06:14:05 【问题描述】:我已经在我的 SceneDelegate 中以编程方式设置了 NavigationController。我的应用程序逻辑需要在某个阶段返回到堆栈上的特定 ViewController。问题是当我使用popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]?
执行此操作时,我似乎失去了对 NavigationController 的跟踪——即使我没有弹回根控制器,也没有可用的后退按钮。
当我在有问题的 ViewController 中时,我的 NavigationController 的 ViewControllers 堆栈如下所示:
(lldb) po navigationController?.viewControllers
▿ Optional<Array<UIViewController>>
▿ some : 4 elements
▿ 0 : <Vocabulary.MainViewController: 0x7fbd4570dcd0>
▿ 1 : <Vocabulary.VocabularyViewController: 0x7fbd4566ce80>
▿ 2 : <Vocabulary.LearnViewController: 0x7fbd45532180>
▿ 3 : <Vocabulary.LearnResultViewController: 0x7fbd4569f900>
(lldb) po mainNavigationController.viewControllers
▿ 4 elements
▿ 0 : <Vocabulary.MainViewController: 0x7fbd4570dcd0>
▿ 1 : <Vocabulary.VocabularyViewController: 0x7fbd4566ce80>
▿ 2 : <Vocabulary.LearnViewController: 0x7fbd45532180>
▿ 3 : <Vocabulary.LearnResultViewController: 0x7fbd4569f900>
我现在像这样在LearnResultViewController
中弹回navigationController.viewControllers[1]
:
override func willMove(toParent parent: UIViewController?)
if let _ = mainNavigationController.topViewController?.isKind(of: LearnResultViewController.self)
if isPresenting
if let vocabularyViewController = mainNavigationController.viewControllers.first(where: $0 is VocabularyViewController )
mainNavigationController.popToViewController(vocabularyViewController, animated: true)
//navigationController?.popToViewController(vocabularyViewController, animated: true) //same behavior
isPresenting
只是我在viewDidLoad
中的LearnViewController
中设置的标志,因为在输入LearnViewController
时已经调用willMove
,显然我只想在离开时弹出,mainNavigationController
是一个全局变量对现在(主要是因为我认为它应该是全局的,以便可以从到目前为止没有帮助的任何地方引用它......)。
现在,当我按下返回按钮时,我可以返回到VocabularyViewController
,但那里不再有返回按钮 - 所以我的 NavigationController 的堆栈似乎丢失了。强>
虽然仍在willMove
中,但我可以看到LearnResultViewController.navigationController
变为nil
- 这导致了我的问题。上面提到的mainNavigationController
到那时还有状态,但是“本地”navigationController becomes
nil:
(lldb) po mainNavigationController.viewControllers
▿ 2 elements
▿ 0 : <Vocabulary.MainViewController: 0x7fbd4570dcd0>
▿ 1 : <Vocabulary.VocabularyViewController: 0x7fbd4566ce80>
(lldb) po navigationController?.viewControllers
nil
(lldb) po navigationController
nil
在将堆栈/状态保留在 NavigationController 中的同时,我该怎么做才能返回到所需的 ViewController?我应该采取其他方法吗?
坦率地说,我什至不明白为什么场景的 navigationController 首先设置为 nil...
【问题讨论】:
【参考方案1】:我试过你的方法,真的不行。
您应该从 LearnResultViewController 的导航堆栈中删除 LearnViewController。
navigationController?.viewControllers.removeAll(where: $0 is LearnViewController )
之后,当您点击返回按钮时,您将返回到 VocabularyViewController。并且后退按钮将在那里。
您不应该为此覆盖 willMove。
【讨论】:
太棒了——就像一个魅力!澄清一下:我现在只是在LearnResultViewController
的 viewDidLoad
中运行提到的代码。通过在弹出之前删除不需要的LearnViewController
,我可以弹出回所需的VocabularyViewController
(它提供了单词的概述而不是再次学习它们的界面)。感谢您的帮助,弗拉迪斯拉夫!【参考方案2】:
对于 Swift 4.0
for controller in self.navigationController!.viewControllers as Array
if controller.isKind(of: DashboardVC.self)
_ = self.navigationController!.popToViewController(controller, animated: true)
break
对于 Swift 3
let viewControllers: [UIViewController] = self.navigationController!.viewControllers
for aViewController in viewControllers
if aViewController is YourViewController
self.navigationController!.popToViewController(aViewController, animated: true)
【讨论】:
感谢您的输入,但它并没有解决我的问题...我已经取回了目标 viewController 的一个实例,并且成功地弹回了它——但是当我这样做时, viewController 不再嵌入在 navigationController 中...以上是关于弹出到 NavigationController 堆栈中的特定 ViewController的主要内容,如果未能解决你的问题,请参考以下文章
为啥 DetailViewController 使用 Tabbar 和 Navigation Controller 弹出到第一个 DetailViewController?