ios-无论视图层次如何,都在所有内容之上显示UIAlertController
我正在尝试提供一个帮助类,以呈现一个UIAlertController
。由于它是一个帮助器类,因此我希望它能在不考虑视图层次结构的情况下正常工作,并且没有有关它的信息。我能够显示警报,但是当它被关闭时,该应用程序崩溃并显示:
*** 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
因为这将取决于当前视图层次结构,而我希望弹出窗口是独立的
编辑:快速解决方案感谢@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)
}
}
回答:
只需显示当前最顶层视图控制器中的视图控制器/警报即可。那可行 :)
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)
}
显然,此技术下的方法 :(
我会在有时间调查时会更新…
这是它的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 Controllers层次结构的约束!
以上是 ios-无论视图层次如何,都在所有内容之上显示UIAlertController 的全部内容, 来源链接: utcz.com/qa/419565.html