ios - 为什么在 UINavigationController 上关闭 UIAlertController 调用关闭?
问题描述
我试图理解为什么从导航中显示的视图控制器中关闭 UIAlertController 时会调用dimiss(animetaded:)
UINavigationController 上的。
原因是我从 UINavigationController 继承了一些逻辑,以便在导航被解除时添加一些逻辑,但每次解除警报时都会无意中调用它。
据我了解,presentingViewController负责关闭呈现的控制器,但这里似乎并非如此。
我错过了什么?
要重现,请运行下面的代码,它将记录消息“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)
}
}
现在从任何地方展示导航控制器。
let contrl = RootViewController()
contrl.view.backgroundColor = .red
contrl.definesPresentationContext = true
let nav = Nav(rootViewController: contrl)
present(nav, animated: true, completion: nil)
编辑:更新代码以使RootViewController定义演示上下文。Edit2:更新代码以更好地表示场景。
解决方案
原因是导航控制器是显示警报控制器的控制器,即使您调用present
视图控制器也是如此。通话也是如此dismiss
。
如果您希望视图控制器显示警报,请将其definesPresentationContext
属性设置为true
.
请参阅https://developer.apple.com/documentation/uikit/uiviewcontroller/1621380-present ...
您调用此方法的对象可能并不总是处理演示文稿的对象。每种演示风格都有不同的规则来管理其行为。例如,全屏演示必须由本身覆盖整个屏幕的视图控制器进行。如果当前视图控制器无法满足请求,它会将请求沿视图控制器层次结构向上转发到其最近的父级,然后父级可以处理或转发该请求。
当使用 UIModalPresentationStyle.currentContext 或 UIModalPresentationStyle.overCurrentContext 样式呈现视图控制器时,此属性控制视图控制器层次结构中的哪个现有视图控制器实际上被新内容覆盖。当基于上下文的展示发生时,UIKit 从展示的视图控制器开始,并沿着视图控制器层次结构向上走。如果它找到了一个视图控制器,其该属性的值为真,它会要求该视图控制器呈现新的视图控制器。如果没有视图控制器定义表示上下文,UIKit 会要求窗口的根视图控制器来处理表示。此属性的默认值为 false。一些系统提供的视图控制器,例如 UINavigationController,将默认值更改为 true。
更新:
对于您的特定问题(如果我理解正确的话),也许它是保持演示逻辑原样(导航控制器呈现)的最佳解决方案,而是在导航控制器的解除方法中添加一个检查:
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
if !(presentedViewController is UIAlertController) {
// your additional logic
}
super.dismiss(animated: flag, completion: completion)
}
推荐阅读
- python - 如何仅在 while 循环中运行 1 次操作
- javascript - 触发反应选择 onchange
- php - 在 php api 上验证图像文件时出错
- python - 安装 web3 时如何解决此错误
- java - 每次加载页面时,如何使用 Hibernate 将自动增量计数保存在数据库中?
- reactjs - @react-three/fiber 节点模块在 Expo 应用程序中不起作用
- css - 尝试设置输入类型范围的样式,但拇指未设置样式
- javascript - For 循环在 Firefox 上运行良好,但在 Chrome 上不行
- security - 如何在电子邮件中执行回归以确保安全。假设我想验证电子邮件是否属于我的组织域
- c# - C#与TcpClient通信