Search code examples
iosswiftxcodecompletion

Completion handler not working (all tasks are executed at the same time)


I have multiple Labels, and I want them to be animated one after the other. So I've built a completion handler that should execute the next task after the previous one has finished. (firstTask -> secondTask -> thirdTask -> fourthTask at the very end.)

But for some reason all animations are executed at the same time. What am I doing wrong?

func firstTask(completion: (_ success: Bool) -> Void) {
    UIView.transition(with: labelOne,
         duration: 1,
          options: .transitionCrossDissolve,
       animations: { [weak self] in
           self?.labelOne.text = arrayOne[GenOne]
    }, completion: nil)
    completion(true)
}

// two more tasks in between just like the firstTask func …

func fourthTask() {
    UIView.transition(with: labelFour,
         duration: 1,
          options: .transitionCrossDissolve,
       animations: { [weak self] in
           self?.labelFour.text = arrayFour[GenFour]
    }, completion: nil)
}

The completion handler:

firstTask { (success) -> Void in
    if success {
        secondTask { (success2) -> Void in
            if success2 {
                thirdTask { (success3) -> Void in
                    if success3 {
                        fourthTask()
                    }
                }
            }
        }
    }
}

Solution

  • When you use a completion handler you need to assign the variable where you write the function so it can be used when you call it. For example:

        func changeLabel(completion: (Bool) -> Void)) {
            //insert whatever you want the function do 
            if (whateverYouWantedToHappenCompletes) {
               completion(true)
            } else {
               completion(false)
            }
        }
        
        changeLabel { (success) in 
           //now you can use the success parameter
        }
    

    If you can't figure this out, look up some videos on how to use completion handlers, or another valid option is to use the built-in completion handler under UIView.animate