展开多个导航控制器

Posted

技术标签:

【中文标题】展开多个导航控制器【英文标题】:Unwind multiple navigation controllers 【发布时间】:2018-01-01 01:56:32 【问题描述】:

假设我在导航控制器中嵌入了视图控制器 A、B 和 C。从 C 开始,我为单独的逻辑流提供了一个新的导航控制器,但需要在完成后返回到 A。所以应用流程如下:A->B->C -- 模态呈现新的导航控制器 -- D->E->F。然后从 F 回到 A。

我已经设置了一个 unwind segue,然而,即使我已经将它设置为返回 A,unwind segue 也只会将我带回 D。

我怎样才能让它一直放松回到 A?我错过了我看不到的东西吗?谢谢。

A 内:

    @IBAction func unwindToHome(segue:UIStoryboardSegue)

然后我从 F 控制拖到它的“退出”并选择了我在 A 中创建的展开转场,并编写了以下转场代码:

    private let SEGUE_TO_HOME = "unwindToHome"
    performSegue(withIdentifier: SEGUE_TO_HOME, sender: nil)

【问题讨论】:

什么是 D、E、F? 实际上,你明白了@Rob!出于某种原因,我也将它放在 D 中...附带问题..我在上述所有视图控制器中都放置了一个 deinit 方法。我只打印所有这些单词中的消失。当它回到 A 时,'gone' 只打印两次。 unwind segue 不会释放所有实例吗? @Rob 再次感谢,现在正在研究强引用。如果这对您很重要,我可以接受您发布的答案 【参考方案1】:

当您展开时,它应该返回视图控制器链,通过所有这些导航控制器和模式表示,一直到实现了此展开操作的视图控制器。

unwindToHome 是否可能出现在除 A 之外的任何这些视图控制器中?这是我能看到的唯一方法 unwind 动作不会把你一直送回 A。我想知道,例如,D 是否有自己的 unwindToHome 动作(或者可能是同一类型的另一个实例作为一个)。最重要的是,我无法重现您描述的行为,除非通过类似的方式。

你随后问:

我在上述所有视图控制器中都添加了deinit 方法。我只打印所有这些单词中的消失。当它回到 A 时,'gone' 只打印两次。 unwind segue 不会释放所有实例吗?

是的,它们都应该被释放。如果没有,“调试内存图”(请参阅https://***.com/a/30993476/1271826)非常擅长显示对未释放内存的强引用。最有可能的是,这些未释放的视图控制器有一些挥之不去的强引用循环、重复的计时器引用或类似的东西,它们分别保持对每个的强引用。

【讨论】:

【参考方案2】:

您可以通过为第二个导航控制器创建子类来简单地创建对控制器 A-C 嵌入的第一个导航控制器的引用。

class SecondNavController: UINavigationController 

  // getter for previous nav controller
  var prevNavController: UINavigationController? 
    return parent?.navigationController
  


当您需要放松时,只需:

class FController: UIViewController 

  // other code

  func unwindToRootController() 
    guard let navController = navigationController as? SecondNavController,
      let prevNavController = navController.prevNavController else 
      return
    
    navigationController.popToRootViewController(animated: true)
  


【讨论】:

以上是关于展开多个导航控制器的主要内容,如果未能解决你的问题,请参考以下文章

在多个故事板环境中展开 segue

返回导航到根视图控制器后,折叠的大标题导航栏变得展开

如何展开到导航堆栈上的第一个视图控制器

展开 Segue 导致清晰的导航栏

如何在多个 .xib 文件之间执行展开转场(不使用情节提要)

从导航控制器内的表视图控制器中的按钮展开