How to update UIProgressView properly in swift iOS

I m trying to show some long running task progress using UIProgressView.


This is my complete and only class:


class ViewController: UIViewController {


var tempValuesArray = NSMutableArray ()

@IBOutlet weak var progressView: UIProgressView!

@IBOutlet weak var progressLabel: UILabel!

override func viewDidLoad() {

super.viewDidLoad()

progressView.progress = 0.0

}


override func viewDidAppear(_ animated: Bool) {

setTempData()

}

func setTempData() {

var i = 0

while i < 100000 {

tempValuesArray.add("Test String")

i += 1

}

testItNow()

}

func testItNow() {

var i = 0

var prog : Float = 0.10

let step : Float = (Float(1.0) / Float(tempValuesArray.count)) * 0.90

print(step)

while i < tempValuesArray.count {

print("***---***")

print(prog)

self.progressView.setProgress(prog, animated: true)

progressLabel.text = String(prog)

prog += step

i = i + 1

print("@@@---@@@")

}

}

}



Problem is
ProgressView and Label are updating instantly at the end

I want them to update with the loop running... To show the real progress...


Am I doing something wrong?
Or is there any other way to acheive this.

You have a thread issue.

The drawing of progress are stacked in the main queue and executed only at some point, at the end.


So the solution is to run the loop in a user thread, and call the main thread when you need to draw (that is compulsory).

So, change testItNow as follows (all steps will not show, because there is still some management of refresh in the main thread, but it is much better):


     func testItNow() {
          var i = 0
          var prog : Float = 0.10
          let step : Float = (Float(1.0) / Float(tempValuesArray.count)) * 0.90
          print(step)
          DispatchQueue.global().async {
               while i < self.tempValuesArray.count {
                    print(prog)             
                    DispatchQueue.main.async { () -> Void in
                         self.progressView.setProgress(prog, animated: true)
                         self.progressLabel.text = String(prog)
                    }
                    prog += step
                    i = i + 1
               }
          }
     }


Notes:

- your code will need a small change, it stops at 1.00003: check step value

- print(prog) slows down execution, hence you see a smoother animation than without it

How to update UIProgressView properly in swift iOS
 
 
Q