0

I want my Progress Bar to update every milliseconds. How would I do this? Currently, it updates every second, which is not what I want.

EDIT: Sorry, I forgot to mention that I still want the timer label to update every second (So it will go down by seconds not milliseconds: 10, 9, 8) while updating the progress bar every milliseconds or 25 times every second.

Code:

 progressBar.transform = progressBar.transform.scaledBy(x: 1, y: 5)
        progressBar.layer.cornerRadius = 5
        progressBar.clipsToBounds = true
        progressBar.layer.sublayers![1].cornerRadius = 5
        progressBar.subviews[1].clipsToBounds = true

func startTimer() {

    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerUpdate), userInfo: nil, repeats: true)

}

@objc func timerUpdate() {

    if timeRemaining <= 0 {
        progressBar.setProgress(Float(0), animated: false)
        bonusTimerLabel.text = "0"
        bonusTimerLabel.textColor = UIColor(red: 186/255, green: 16/255, blue: 16/255, alpha: 1)

    } else {
        progressBar.setProgress(Float(timeRemaining)/Float(10), animated: false)
        timeRemaining -= 1
        bonusTimerLabel.text = "\(timeRemaining)"
    }
BlueBear
  • 23
  • 6
  • i think this is a heavy process , eye event won't notice that – Shehata Gamal Jan 15 '19 at 22:54
  • Please read the documentation for Timer. You won’t get millisecond resolution. And there no need for it. There’s no reason to update a progress bar 1000 times per second. 25 times per second is more than you would possibly need. – rmaddy Jan 15 '19 at 22:57

2 Answers2

0

Firing a function with timer every millisecond is not advisable, reference: https://stackoverflow.com/a/30983444/8447312

So you can fire timer func every 50 millisecond to be safe and update your progress bar. That shouldn't be too observable though.

Also make sure timeRemaining is a Double, and then just try:

func startTimer() {

    timer = Timer.scheduledTimer(timeInterval: 0.050, target: self, selector: #selector(timerUpdate), userInfo: nil, repeats: true)

}

@objc func timerUpdate() {

    if timeRemaining <= 0 {
        progressBar.setProgress(Float(0), animated: false)
        bonusTimerLabel.text = "0"
        bonusTimerLabel.textColor = UIColor(red: 186/255, green: 16/255, blue: 16/255, alpha: 1)

    } else {
        progressBar.setProgress(Float(timeRemaining)/Float(20), animated: false)
        timeRemaining -= 0.050
        bonusTimerLabel.text = "\(Int(timeRemaining))"
    }
emrepun
  • 2,496
  • 2
  • 15
  • 33
  • But I still want the text label to update every second. How would I do this? – BlueBear Jan 15 '19 at 23:15
  • It should work like that. Did you try the code? Also can you edit your question and show how you declare timeRemaining? – emrepun Jan 15 '19 at 23:24
  • @BlueBear you should never rely on a timer to measure elapsed time interval between two moments in time (two dates). Just store the start time `let startDate = Date()` and use the timer only to update the user interface with the `let elapsedTime = Date().timeIntervalSince(startDate)`. You shouldn't need more than 30fps `1/30` when displaying it. – Leo Dabus Jan 16 '19 at 00:23
0

1 millisecond is 0.001 second. So change timerInterval property in timer to 0.001:

timer = Timer.scheduledTimer(timeInterval: 0.001, target: self, selector: #selector(timerUpdate), userInfo: nil, repeats: true)
jMelvins
  • 194
  • 1
  • 10