julianmark
julianmark

Reputation: 40

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()
                    }
                }
            }
        }
    }
}

Upvotes: 1

Views: 483

Answers (2)

Reinier Melian
Reinier Melian

Reputation: 20804

You need to execute your completion block, when animation finish, that happens on completion block of animation

func firstTask(completion: @escaping ((_ success: Bool) -> Void)) {
    UIView.transition(with: randomOne, duration: 1, options: .transitionCrossDissolve, animations: {
        self?.randomOne.text = location[RandomWordGenOne]
    }) { (finished) in
        completion(true)
    }
}

Upvotes: 2

Nick Viscomi
Nick Viscomi

Reputation: 26

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

Upvotes: -1

Related Questions