Every UIAlertController disappear automatically before user responds - since iOS 13

后端 未结 3 1357
孤城傲影
孤城傲影 2020-12-09 13:01

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

相关标签:
3条回答
  • 2020-12-09 13:23

    You can try this solution also. It is working form me.

    write below method in your class.

    func presentViewController(alertController: UIAlertController, completion: (() -> Void)? = nil) {
            if var topController = UIApplication.shared.keyWindow?.rootViewController {
                while let presentedViewController = topController.presentedViewController {
                    topController = presentedViewController
                }
    
                DispatchQueue.main.async {
                    topController.present(alertController, animated: true, completion: completion)
                }
            }
        }
    

    Then call it from your code as below

    let alertController = UIAlertController(title: "Discard Photo?",
                                                    message: "Your photo will not be attached",
                                                    preferredStyle: .alert)
            alertController.addAction(UIAlertAction(title: "Keep Photo", style: .default, handler: nil))
            alertController.addAction(UIAlertAction(title: "Discard", style: .default) { (_) -> Void in
                self.PhotoStack.deletePhoto(at: index)
                self.cameraBtn.isEnabled = true
            })
    
            self.presentViewController(alertController: alertController)
    
    0 讨论(0)
  • 2020-12-09 13:33

    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
    
    0 讨论(0)
  • 2020-12-09 13:35

    Based on pepsy answer. If you don't want to care about alertWindow.isHidden = true stuff, you can do something like this:

    class AlertHandler {
        private static let alertWindow: UIWindow = {
            let window = UIWindow(frame: UIScreen.main.bounds)
            window.windowLevel = UIWindow.Level.alert + 1
            return window
        }()
    
        private var alertController: UIAlertController
    
        init(title: String?,
             message: String?) {
            alertController = UIAlertController(title: title,
                                                message: message,
                                                preferredStyle: .alert)
        }
    
        func addAction(title: String?,
                       style: UIAlertAction.Style,
                       handler: ((UIAlertAction) -> Void)? = nil) {
            let action = UIAlertAction(title: title,
                                       style: style) { action in
                                        handler?(action)
                                        AlertHandler.alertWindow.isHidden = true
            }
            alertController.addAction(action)
        }
    
        func present() {
            AlertHandler.alertWindow.rootViewController = UIViewController()
            AlertHandler.alertWindow.makeKeyAndVisible()
            AlertHandler.alertWindow.rootViewController?.present(alertController,
                                                                 animated: true,
                                                                 completion: nil)
        }
    }
    
    0 讨论(0)
提交回复
热议问题