2

I'm trying to implement a UIAlertController that is presented on top of the window and stays that way until the user closes it, even if the application attempts to push another view controller.

I've read those questions and answers:

And while in versions previous to iOS 13 the provided solutions worked like a charm, I'm stuck trying to solve this issue in iOS 13:

When I show the UIAlertController, it stays in top until another view controller gets pushed in the navigation stack. If this happens, the UIAlertController disappears.

func showHighPriorityNotification() {
    let alertWindow = UIWindow(frame: UIScreen.main.bounds)
    alertWindow.rootViewController = UIViewController()
    alertWindow.windowLevel = UIWindowLevelAlert + 1
    alertWindow.makeKeyAndVisible()

    let alertController = UIAlertController(title: "Title"), message: "Message"), preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "Button"), style: .default))

    if #available(iOS 13, *) {
        // Trying to get this functionality to work in iOS 13.
        if var topController = alertWindow.rootViewController {
            while let presentedViewController = topController.presentedViewController {
                topController = presentedViewController
            }
            topController.modalPresentationStyle = .fullScreen
            topController.present(alertController, animated: true)
        }
    } else {
        // This code works in iOS 12 and below, but NOT in iOS 13.
        alertWindow.rootViewController?.present(alertController, animated: true)
    }
}

In iOS13, is there some way to keep the UIAlertController on top and allow views to get pushed below it? As I've said, in previous versions this just works nicely.

IloneSP
  • 429
  • 2
  • 13
  • why are you using #available(iOS 13, *)? the funcionality is the same for all of versions –  Feb 14 '20 at 13:52
  • @x-rw Check the linked questions, but basically Apple changed the `present` behaviour in iOS 13. I've been trying to solve the issue in the #available. – IloneSP Feb 14 '20 at 14:00
  • 1
    If you'd present the `alertController` in your `alertWindow`, does it show up and disappears almost instantly? If so, try this: https://stackoverflow.com/questions/58131996/every-uialertcontroller-disappear-automatically-before-user-responds-since-ios/58133993#58133993 – pepsy Feb 20 '20 at 11:56
  • 1
    You should make that an answer, @pepsy :P – IloneSP Feb 20 '20 at 16:10

1 Answers1

1

You can use the same implementation as you used in iOS 12 and below, but you must hold a strong reference to the window you are presenting the alert on.

In your current code - when running on iOS 13 - the alertWindow will be destroyed as soon as showHighPriorityNotification finishes, dismissing your alert. It can be fixed by holding a strong reference to the alertWindow somewhere else.

Check this answer for a way of implementing that.

pepsy
  • 1,437
  • 12
  • 13