Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Every UIAlertController disappear automatically before user responds - since iOS 13

Since I'm using iOS 13, each of my UIAlertController shows up for about half a second and disappears instantly before any user action. Any idea ?

As I use UIAlertController from different parts of my app, I use an extension that allows me to pop up both from classical views and collectionView (cell, header etc...)

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

And here is an example of this extension use :

fileprivate func showMissingAlert() {
        let alert = UIAlertController(title: "blablabla", message: "blablablablabla blabla", preferredStyle: UIAlertController.Style.alert)
        alert.show()
        alert.view.tintColor = Theme.mainAccentColor
        let cancelAction = UIAlertAction(title: "OK, blabla", style: .default, handler: {(alert: UIAlertAction!) in print("ok, leave")})
        alert.addAction(cancelAction)
    }

And further in my code :

showMissingAlert()

Before iOS 13, every UIAlert worked fine... Since I moved to iOS 13, and even iOS 13.1, it became a big mess... :(

  • Any idea about what could cause this?

  • And how to prevent using UIAlert as subliminal message :) ?

like image 815
Creanomy Avatar asked Sep 27 '19 09:09

Creanomy


People also ask

How do you dismiss an alert with click on outside of the alert IOS?

Step 1 − Open Xcode and create a single view application and name it UIAlertSample. So basically, when we tap on the button an alert will be displayed, when the user taps outside the alert the alert will be dismissing.

How do you dismiss an alert controller in Swift?

GitHub - SwiftGuides/Dismiss-AlertViewController-on-clicking-tapping-outside-the-alert: It will dismiss the alert when clicking outside of the alert popup.


2 Answers

Before you considered to make alertController in window, please check your animation or other UI things animated together.

e.g, if you do self.dismiss(VC) and self.present(alertController) together, it makes problem

Best way to develop is not ignore irregular ui events, but check any other things first which has some problems.

like image 158
Kyle Yi Avatar answered Sep 28 '22 08:09

Kyle Yi


I've got exactly the same problem, and fixed it by holding the window in which the alert is being presented in a strong variable.

You can hold a window for presenting alerts in you AppDelegate, for example, and use it in your UIAlertController extension.

//In app delegate
let alertWindow: UIWindow = {
    let win = UIWindow(frame: UIScreen.main.bounds)
    win.windowLevel = UIWindow.Level.alert + 1
    return win
}()

Then, in your extension:

public extension UIAlertController {
    func show() {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let vc = UIViewController()
        vc.view.backgroundColor = .clear
        vc.view.tintColor = Theme.mainAccentColor
        appDelegate.alertWindow.rootViewController = vc
        appDelegate.alertWindow.makeKeyAndVisible()
        vc.present(self, animated: true, completion: nil)
    }
}

You will also need to make sure your alert window is removed from view when your alert is dismissed, otherwise your app will become unresponsive, as all taps will be handled by the (invisible) alert window, that's still on top of everything. I do this by adding this code to the handlers of all actions in the alert:

(UIApplication.shared.delegate as! AppDelegate).alertWindow.isHidden = true
like image 20
pepsy Avatar answered Sep 28 '22 08:09

pepsy