Ref:
How to present UIAlertController when not in a view controller?
<aside> 💡 Use an additional UIWindow
</aside>
When you want to display your UIAlertController:
window.makeKeyAndVisible()
)window.rootViewController = UIViewController()
)A couple things to note:
window.windowLevel = UIWindowLevelAlert + 1
)check if alert exists before present alert
// <https://stackoverflow.com/a/58295128/5588637>
class WindowAlertPresentationController: UIViewController {
// MARK: - Properties
private lazy var window: UIWindow? = UIWindow(frame: UIScreen.main.bounds)
private let alert: UIAlertController
// MARK: - Initialization
init(alert: UIAlertController) {
self.alert = alert
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("This initializer is not supported")
}
// MARK: - Presentation
func present(showOnceOnly: Bool = false, animated: Bool, completion: (() -> Void)?) {
if showOnceOnly {
var existed = false
for window in UIApplication.shared.windows {
if window.rootViewController is WindowAlertPresentationController {
existed = true
break
}
}
if !existed {
window?.rootViewController = self
window?.windowLevel = UIWindow.Level.alert + 1
window?.makeKeyAndVisible()
present(alert, animated: animated, completion: completion)
}
} else {
window?.rootViewController = self
window?.windowLevel = UIWindow.Level.alert + 1
window?.makeKeyAndVisible()
present(alert, animated: animated, completion: completion)
}
}
// MARK: - Overrides
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
super.dismiss(animated: flag) {
self.window = nil
completion?()
}
}
}
extension UIAlertController {
func presentInOwnWindow(showOnceOnly: Bool, animated: Bool, completion: (() -> Void)?) {
let windowAlertPresentationController = WindowAlertPresentationController(alert: self)
windowAlertPresentationController.present(showOnceOnly: showOnceOnly, animated: animated, completion: completion)
}
}