Swift 难以理解 UINavigationController 和 navigationController re: presentingViewController

Swift difficulty understanding UINavigationController & navigationController re: presentingViewController

我的代码有效,但我正在尝试理解它。这是一些用于管理 "Cancel" 按钮的代码,该按钮可以从 "Show" segue(当用户单击 table 视图单元格进行编辑时显示)或 return "Present Modally" segue(当用户单击“+”栏按钮项以将新单元格添加到 table 视图时)。下图。我对 UINavigationController 和 navigationController 属性 感到困惑。如果我遗漏了一些非常明显的东西,我们深表歉意。

// Apple says below is nil if neither the current view controller nor any of its ancestors were presented modally
let isPresentingInAddMode = presentingViewController is UINavigationController
if isPresentingInAddMode {
    // Modal segues need to be dismissed
    dismiss(animated: true, completion: nil)
} else {
    // But Show segues are "popped" off of a stack of controllers.
        navigationController!.popViewController(animated: true)
}

以下是我不理解的地方: - 如果我通过 "Show" segue 到达 Detail View Controller,在执行期间暂停,并选择单击 navigationController,Xcode 说它是 UINavigationController?如果我在 else 条件下暂停执行并使用调试器来: 导航控制器! == 无 - Xcode 表示它的计算结果为 false,因此 navigationController 是一个有效的 UINavigationController。

那么为什么

presentingViewController is UINavigationController 

当我使用 "Show"?
表示时,在最上面的语句中等于 true 也许我不明白"present"。呈现的东西只发生在模态转场中,所以没有 presentingViewController? 如果我回顾一下我的故事板(见下图),Detail View Controller 的祖先之一是 table 视图控制器,其中嵌入了一个导航控制器,考虑到 Apple 对 presentingViewController 的定义,不应该: presentingViewController 是 UINavigationController 在这种情况下也是如此吗?

并且会:

presentingViewController != nil

实现相同的结果还是有重要原因验证 presentingViewController 是 UINavigationController?

非常感谢好心人帮我解析这个问题。 约翰

"ShowDetail" segue 是源自 table 视图单元格的 "Show" segue。 "AddItem" segue 属于 "Present Modally" 类型,源自“+”添加栏按钮项。

可能没有必要在 table 视图控制器中查看 prepare for segue 代码,但如果您好奇:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
    if segue.identifier == "ShowDetail" {  // is this the "ShowDetail" segue? and if it is...
        // ... get the IndexPath for the row the user clicked on (the selected row)
        let indexPath = tableView.indexPathForSelectedRow!
        let destinationViewController = segue.destination as! DetailViewController // downcast the destination as the specific class DetailViewController
        // Get the to do item that the user clicked on
        let selectedToDo = toDoArray[indexPath.row]
        // Pass selectedToDo to the toDoItem variable in our destinationViewController
        destinationViewController.toDoItem = selectedToDo
    }
}

Perhaps I'm not understanding "present".

也许吧。让我们看一下图表:

有两个常用的built-in转场:

  • Show,原名Push。如果在 UINavigationController 情况下使用,按预期调用 pushViewController。推送的视图控制器有一个 navigationController。 return 是通过调用 popViewController 来执行的。

  • 现在,原名莫代尔。调用 presentViewController(现在调用 present)。呈现的视图控制器有一个 presentingViewController。 return 通过调用 dismiss.

  • 执行

但是,有一个复杂的问题可能会让您感到困惑:如果在 UINavigationController 情况下使用 show 而不是 ,宇宙不会像预期的那样爆炸,它会神奇地变成本身变成 present.