gpt4 book ai didi

ios - 无论 View 层次结构如何,都将 UIAlertController 呈现在所有内容之上

转载 作者:IT王子 更新时间:2023-10-29 05:05:04 26 4
gpt4 key购买 nike

我正在尝试创建一个显示 UIAlertController 的辅助类。因为它是一个辅助类,所以我希望它能在不考虑 View 层次结构的情况下工作,并且没有关于它的信息。我能够显示警报,但是当它被解除时,应用程序崩溃了:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Trying to dismiss UIAlertController <UIAlertController: 0x135d70d80>
with unknown presenter.'

我正在创建弹出窗口:

guard let window = UIApplication.shared.keyWindow else { return }
let view = UIView()
view.isUserInteractionEnabled = true
window.insertSubview(view, at: 0)
window.bringSubview(toFront: view)
// add full screen constraints to view ...

let controller = UIAlertController(
title: "confirm deletion?",
message: ":)",
preferredStyle: .alert
)

let deleteAction = UIAlertAction(
title: "yes",
style: .destructive,
handler: { _ in
DispatchQueue.main.async {
view.removeFromSuperview()
completion()
}
}
)
controller.addAction(deleteAction)

view.insertSubview(controller.view, at: 0)
view.bringSubview(toFront: controller.view)
// add centering constraints to controller.view ...

当我点击 yes 时,应用程序将崩溃,并且处理程序在崩溃前未被命中。我无法显示 UIAlertController,因为这将依赖于当前 View 层次结构,而我希望弹出窗口是独立的

编辑:Swift 解决方案感谢@Vlad 的想法。似乎在单独的窗口中操作要简单得多。所以这是一个有效的 Swift 解决方案:

class Popup {
private var alertWindow: UIWindow
static var shared = Popup()

init() {
alertWindow = UIWindow(frame: UIScreen.main.bounds)
alertWindow.rootViewController = UIViewController()
alertWindow.windowLevel = UIWindowLevelAlert + 1
alertWindow.makeKeyAndVisible()
alertWindow.isHidden = true
}

private func show(completion: @escaping ((Bool) -> Void)) {
let controller = UIAlertController(
title: "Want to do it?",
message: "message",
preferredStyle: .alert
)

let yesAction = UIAlertAction(
title: "Yes",
style: .default,
handler: { _ in
DispatchQueue.main.async {
self.alertWindow.isHidden = true
completion(true)
}
})

let noAction = UIAlertAction(
title: "Not now",
style: .destructive,
handler: { _ in
DispatchQueue.main.async {
self.alertWindow.isHidden = true
completion(false)
}
})

controller.addAction(noAction)
controller.addAction(yesAction)
self.alertWindow.isHidden = false
alertWindow.rootViewController?.present(controller, animated: false)
}
}

最佳答案

2019 年 12 月 16 日更新:

只需显示当前最顶层 View Controller 的 View Controller /警报。那会起作用:)

if #available(iOS 13.0, *) {
if var topController = UIApplication.shared.keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
topController.present(self, animated: true, completion: nil)
}

2019 年 7 月 23 日更新:

重要

显然,此技术下面的方法在 iOS 13.0 中停止工作 :(

一旦有时间调查,我会更新...

旧技术:

这是它的 Swift (5) 扩展:

public extension UIAlertController {
func show() {
let win = UIWindow(frame: UIScreen.main.bounds)
let vc = UIViewController()
vc.view.backgroundColor = .clear
win.rootViewController = vc
win.windowLevel = UIWindow.Level.alert + 1 // Swift 3-4: UIWindowLevelAlert + 1
win.makeKeyAndVisible()
vc.present(self, animated: true, completion: nil)
}
}

只需设置您的 UIAlertController,然后调用:

alert.show()

不再受 View Controller 层次结构的约束!

关于ios - 无论 View 层次结构如何,都将 UIAlertController 呈现在所有内容之上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40991450/

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