delay/sleep in Swift is not working

I have a problem with the sleep function in Swift code. I’m using import Darwin and usleep(400000). Some actions before reaching the sleep are blocked and I dont know why. Here a short example from my code:

@IBAction func Antwort4Button(_ sender: Any) {
    if (richtigeAntwort == "4"){
        Antwort4.backgroundColor = UIColor.green
        Ende.text = "Richtig!"

        NaechsteFrage()
    }
    else {
        Ende.text = "Falsch!"

        //NaechsteFrage()
    }
}

func NaechsteFrage() {
    usleep(400000)

    Antwort1.backgroundColor = UIColor.red
    Antwort2.backgroundColor = UIColor.red
    Antwort3.backgroundColor = UIColor.red
    Antwort4.backgroundColor = UIColor.red

    Ende.text = ""

    FragenSammlung()
}

This lines will be not executed:

  • How to Wait in Objective-C
  • Showing Waiting Alert View At Load
  • Antwort4.backgroundColor = UIColor.green
    
    Ende.text = "Richtig!"
    

    Why is calling sleep blocking these actions? If I delete the import Darwin and the sleep, my code works fine. Has anyone an idea? Sorry for my bad english 😛

    3 Solutions Collect From Internet About “delay/sleep in Swift is not working”

    Others alrady answered the question, I just wanted to provide some additional information (cannot comment yet).

    You said that Antwort4.backgroundColor = UIColor.green is not executed. To clarify, this is executed, but you don’t see the result becuase you call sleep, which is blocking the UI. Here is what happens:

    1. set background color of Antwort4 to green
    2. sleep: block the UI which prevents the app from actually showing the green background
    3. set the background color of Antwort4 to red again

    To solve the problem at hand you can use Apples Displatch API. So instead of sleept, you could use:

    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        self.Antwort1.backgroundColor = UIColor.red
        self.Antwort2.backgroundColor = UIColor.red
        self.Antwort3.backgroundColor = UIColor.red
        self.Antwort4.backgroundColor = UIColor.red
    
        self.Ende.text = ""
    
        self.FragenSammlung()
    }
    

    like @jcaron said

    here the code to do it:

    func delay(delayTime: Double, completionHandler handler:@escaping () -> ()) {
            let newDelay = DispatchTime.now() + delayTime
            DispatchQueue.main.asyncAfter(deadline: newDelay, execute: handler)
        }
    

    Edited: you can create a viewController extension to use in any viewControllers like this:

    extension UIViewController {
    
        func delay(delayTime: Double, completionHandler handler:@escaping () -> ()) {
                let newDelay = DispatchTime.now() + delayTime
                DispatchQueue.main.asyncAfter(deadline: newDelay, execute: handler)
            }
    }
    

    So in your viewController you just call like this:

    delay(delayTime: 2, completionHandler: {
                _ in
                // do your code here
            })
    

    The usleep() function will block your UI. If you don’t want to have this behavior better use the Timer class.