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

回到顶部