ios - 测试 "presentingViewController is UIViewController"在一种情况下工作正常,在其他情况下失败

标签 ios swift uiviewcontroller

按照Apple的文档添加和编辑信息Apple guide here我有一个带有表格 View 的 View Controller 。 TableView 包含一个带有“添加新”按钮的标题。如果选择了表行,detailViewController 就会被插入堆栈。 DetailViewController 也嵌入在 UINavigationController 中,如 Apple 文档中所示。如果按下“添加新”,则会执行另一个 segue,以模态方式呈现 UINavigationController,进而显示明细 View Controller 。这工作得很好,动画清楚地显示了模态呈现的 ViewController。

detailViewController 在导航栏中包含一个取消按钮。如果按下,则会运行以下代码:

@IBAction func cancel(_ sender: UIBarButtonItem) {
    // Depending on style of presentation (modal or push presentation), this view controller needs to be dismissed in two different ways.
    var isPresentingInAddActionMode = false
    if let presentingVC = self.presentingViewController{
     isPresentingInAddActionMode = presentingVC is UINavigationController

    }
    streekgidsModel.undoManager.endUndoGrouping()
    print("undo grouping ended and undone")
    streekgidsModel.undoManager.undo()
    if isPresentingInAddActionMode {
        dismiss(animated: true, completion: nil)
    }
    else if let owningNavigationController = navigationController{
        owningNavigationController.popViewController(animated: true)
    }
    else {
        fatalError("The MealViewController is not inside a navigation controller.")
    }
}

第一个 if 语句检查 PresentingViewController 属性是否存在,如果存在,则检查它的类型是否为 UINavigationController。如果是这样,则 viewController 将以模态方式呈现,并且应该被关闭。如果没有,它就会被压入堆栈,并且 owningNavigationController 应该弹出detailViewController。 运行此代码并不像 Apple 所描述的那样工作。对presentingViewController 的检查显示它存在,但类型检查返回“无效”。这被视为错误。对 owningNavigationController 的测试成功(我认为它应该失败)并且 popViewController 被执行。由于没有推送,因此 View Controller 不会弹出或关闭,并且仍然可见。第二次按“取消”将再次执行 func cancel,这会导致错误,因为撤消管理器中不再启动组。

令人困惑的是,我在另一个 View Controller 中有相同的代码,具有类似的 UIViewTable 和导航,并且工作正常。

因此,为了解决这个问题:为什么这不像苹果描述的那样工作,为什么我的另一个 View Controller 按预期工作?欢迎任何意见。

顺便说一句, fatal error 文本直接来自文档,因此命名不相关,并且永远不会执行。

最佳答案

我首先检查谁是演示者。

根据 Apple 文档:

When you present a view controller modally (either explicitly or implicitly) using the present(_:animated:completion:) method, the view controller that was presented has this property set to the view controller that presented it. If the view controller was not presented modally, but one of its ancestors was, this property contains the view controller that presented the ancestor. If neither the current view controller or any of its ancestors were presented modally, the value in this property is nil.

如果文档正确,那么您的演示者应该是您的“带有 tableview 的 Viewcontroller”,我猜它不是 UINavigationController。如果是这种情况,那么您应该了解代码失败的原因。

当然,这取决于您的上下文,但我会这样简化检查:

var isPresentingInAddActionMode = self.presentingViewController != nil 
... // your other code
if isPresentingInAddActionMode {
    dismiss(animated: true, completion: nil)
}
else if let owningNavigationController = navigationController{
    owningNavigationController.popViewController(animated: true)
}

如果我正确理解了你的问题和意图,那么谁(哪个类)呈现了你的detailVC对你来说并不重要,你只关心你的detailVC是如何呈现的——要么推送到导航 View Controller 中,要么以模态方式呈现。我认为只需检查 presentingViewController 属性就可以获取该信息。

关于ios - 测试 "presentingViewController is UIViewController"在一种情况下工作正常,在其他情况下失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44796437/

相关文章:

ios - 在容器 View 中显示 CNContactPickerViewController?

ios - 为 UINavigationBar 的标题设置一个导航按钮

ios - 所有安装iOS 6的设备都将配备相机吗?

uiviewcontroller - Storyboard - "Round Style Text Field"警告的位置不明确

android - facebook分享视频不播放

ios - 在没有付费苹果开发者帐户的情况下在 swift 中使用应用内购买

arrays - 检查哪个日期最接近今天

ios - 在启动时加载并呈现第二个 View Controller

swift - Swift UIViewController 实现通常使用默认属性值,还是在 viewDidLoad 中初始化属性?

ios - CUICatalog : Invalid asset name supplied: , 或无效比例因子 : 2. 000000