gpt4 book ai didi

ios - 为什么关闭 UIAlertController 会调用 UINavigationController 上的关闭?

转载 作者:行者123 更新时间:2023-11-30 10:56:47 25 4
gpt4 key购买 nike

我试图理解为什么当从导航中显示的 View Controller 中关闭 UIAlertController 时,会调用 UINavigationController 上的 dimiss(animetaded:)

原因是我继承了 UINavigationController 来在导航被解除时添加一些逻辑,但每次警报被解除时都会无意中调用它。

根据我的理解,presentingViewController 负责关闭呈现的 Controller ,但似乎这里的情况并非如此。

我错过了什么?

要重现,请运行下面的代码,它将记录消息“DISMISS ON NAVIGATION”。

    class RootViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

let alert = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: nil))
present(alert, animated: true)
}
}

class Nav: UINavigationController {
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
print("DISMISS ON NAVIGATION")
super.dismiss(animated: flag, completion: nil)
}
}

现在从任何地方呈现导航 Controller 。

            let contrl = RootViewController()
contrl.view.backgroundColor = .red
contrl.definesPresentationContext = true

let nav = Nav(rootViewController: contrl)

present(nav, animated: true, completion: nil)

编辑:更新代码以使RootViewController定义演示上下文。Edit2:更新代码以更好地表示场景。

最佳答案

原因是导航 Controller 是呈现警报 Controller 的 Controller ,即使您在 View Controller 上调用 present 也是如此。 dismiss 调用也是如此。

如果您希望 View Controller 显示警报,请将其 definesPresentationContext 属性设置为 true

参见 https://developer.apple.com/documentation/uikit/uiviewcontroller/1621380-present ...

The object on which you call this method may not always be the one that handles the presentation. Each presentation style has different rules governing its behavior. For example, a full-screen presentation must be made by a view controller that itself covers the entire screen. If the current view controller is unable to fulfill a request, it forwards the request up the view controller hierarchy to its nearest parent, which can then handle or forward the request.

...和https://developer.apple.com/documentation/uikit/uiviewcontroller/1621456-definespresentationcontext:

When using the UIModalPresentationStyle.currentContext or UIModalPresentationStyle.overCurrentContext style to present a view controller, this property controls which existing view controller in your view controller hierarchy is actually covered by the new content. When a context-based presentation occurs, UIKit starts at the presenting view controller and walks up the view controller hierarchy. If it finds a view controller whose value for this property is true, it asks that view controller to present the new view controller. If no view controller defines the presentation context, UIKit asks the window’s root view controller to handle the presentation. The default value for this property is false. Some system-provided view controllers, such as UINavigationController, change the default value to true.

更新:

对于您的具体问题(如果我理解正确的话),也许这是保持演示逻辑不变(导航 Controller 呈现)的最佳解决方案,而是在导航 Controller 的解雇方法中添加检查:

override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
if !(presentedViewController is UIAlertController) {
// your additional logic
}
super.dismiss(animated: flag, completion: completion)
}

关于ios - 为什么关闭 UIAlertController 会调用 UINavigationController 上的关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53885406/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com