Anthony Shahine
Anthony Shahine

Reputation: 2487

Is it possible to block execution of my code until UIAlertController is dismissed?

is there anyway to wait the user to press the button that dismiss the alertController in swift 3, by using DispatchQueue or something else?

Upvotes: 6

Views: 3735

Answers (3)

iUrii
iUrii

Reputation: 13863

You MUST NOT block the main thread and waiting for dismissing your alert so the only way is doing this asynchronously.

For instance you can use next common approach with UIViewControllerTransitioningDelegate:

fileprivate var AssociatedObjectKey: UInt8 = 0

extension UIAlertController : UIViewControllerTransitioningDelegate {
    
    var onDissmiss: (() -> Void)? {
        set {
            transitioningDelegate = newValue != nil ? self : nil
            objc_setAssociatedObject(self, &AssociatedObjectKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        get {
            return objc_getAssociatedObject(self, &AssociatedObjectKey) as? (() -> Void)
        }
    }

    
    public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        onDissmiss?()
        return nil
    }
}

How to use:

let alert = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert)

let ok = UIAlertAction(title: "OK", style: .default)
alert.addAction(ok)

alert.onDissmiss = {
    print("dissmiss")
}

present(alert, animated: true)

Upvotes: -1

zoul
zoul

Reputation: 104145

You mean something like this?

alertController.displayAndWaitUntilDismissed()
// This line is only reached after the alert controller is dismissed
print("Alert controller dismissed.")

Theoretically, yes, you could use a dispatch semaphore to block until the alert is dismissed. But it’s a bad idea – I can’t even think of a scenario where it would be acceptable. Simply accept that you have to deal with it asynchronously, by executing the desired code in the alert controller action.

Upvotes: 1

Sweeper
Sweeper

Reputation: 275085

Just move all the code you want to execute after the alert is dismissed into a separate method. When you're adding UIAlertActions, make all the actions' handler parameter call that method. This way, whichever button the user presses, your code will always be executed!

Upvotes: 2

Related Questions