hyperpringle
hyperpringle

Reputation: 45

Progress bar won't update from for loop

I've been through all similar questions and I can't seem to crack this. I'm trying to iterate through a 10-iteration loop in my xcode project and update the progress bar by 10% every time.

The progress bar doesn't seem to update until the very end, despite my attempts with DispatchQueue.

@IBOutlet weak var signingBar: UIProgressView!
@IBOutlet weak var contButton: UIButton!
@IBAction func goButton(_ sender: UIButton) {

        DispatchQueue.global(qos: .utility).async {
            for i in 1...10 {

                // run function x times
                runSignings(iterations: 1)

                DispatchQueue.main.async {
                    // now update UI on main thread
                    self.signingBar.setProgress(Float(i/10), animated: true)

                    if i == 10 {
                        self.contButton.isHidden = false
                    }
                    else {
                        self.contButton.isHidden = true
                    }
                }
            }
        }
    }

I expect this to run my function through and update the UI at the end of each for loop, but it is currently not updating the progressbar until all loops are complete.

Upvotes: 2

Views: 1353

Answers (1)

Terry
Terry

Reputation: 108

Seems the Float(i/10) should change to Float(i)/10 because the previous one does the division with two integers then convert to float, it will always return 0 until the i reaches to 10.

Also, if I understand your question correctly, you want to update the progress synchronously with each step i.

Because you are using DispatchQueue.main.async to update the signingBar asynchronously in the main thread, so the for loop will still go on but not blocked by self.signingBar.setProgress.

If you want to make sure the signingBar updates step by step, you can use DispatchGroup to wait until the progress bar updated.

// At each 'i' step

let group = DispatchGroup()
group.enter()

// run function x times
runSignings(iterations: 1)

DispatchQueue.main.async {
    // now update UI on main thread
    self.signingBar.setProgress(Float(i)/10, animated: true)

    group.leave()
}

group.wait()

Hope these above can help you.

Upvotes: 1

Related Questions