0

Basically I want to create a UIProgressView to go from 0.0 (empty) to 1.0 (full) in 3 seconds. Could anyone point me in the right direction for using NSTimer in swift with UIProgressView?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
dwinnbrown
  • 3,789
  • 9
  • 35
  • 60

3 Answers3

1

If anyone's interested here is a Swift 5 working version :

extension UIProgressView {
    @available(iOS 10.0, *)
    func setAnimatedProgress(progress: Float = 1, duration: Float = 1, completion: (() -> ())? = nil) {
        Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { (timer) in
            DispatchQueue.main.async {
                let current = self.progress
                self.setProgress(current+(1/duration), animated: true)
            }
            if self.progress >= progress {
                timer.invalidate()
                if completion != nil {
                    completion!()
                }
            }
        }
    }
}

Usage :

// Will fill the progress bar in 70 seconds
self.progressBar.setAnimatedProgress(duration: 70) {
    print("Done!")
}
Que20
  • 1,469
  • 2
  • 13
  • 27
0

Declare the properties:

var time = 0.0
var timer: NSTimer

Initialize the timer:

timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector:Selector("setProgress"), userInfo: nil, repeats: true)

Implement the setProgress function:

func setProgress() {
    time += 0.1
    dispatch_async(dispatch_get_main_queue(), {
        progressView.progress = time / 3 
    })
    if time >= 3 {
        timer.invalidate()
    }
}

(I'm not 100% sure if the dispatch block is necessary, to make sure the UI is updated in the main thread. Feel free to remove this if it isn't necessary.)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
  • I just gave this a go and am getting all kinds of issues :P I set up a new cocoa touch file in swift for the progress bar of type UIProgressView. I am told the class has no initializers. – dwinnbrown Jul 15 '15 at 13:10
  • I assumed the progress view was already defined (in Storyboard or in code). You know how to do that, don't you? – Glorfindel Jul 15 '15 at 13:12
  • What do you mean by define. I am new to coding and can build apps but just don't know the correct terminology yet :P Would an outlet be defining it? – dwinnbrown Jul 15 '15 at 13:22
  • Yes, that's how I would do it: add the progress view in the Storyboard so that you can see where it appears i.r.t. the other elements, and then create an outlet for it. – Glorfindel Jul 15 '15 at 13:23
  • I tried that but it won't let me... I am using split view to show my code on the other side, but it just won't give me the option to put it as an outlet. – dwinnbrown Jul 15 '15 at 13:25
  • Hmm ... that's tough to solve on a platform like StackOverflow. You could try to define the outlet in code, and then Ctrl-drag the progress view to the view controller (this all happens in the storyboard). – Glorfindel Jul 15 '15 at 13:33
0

I created my own solution after searching for one and coming across this question.

extension UIProgressView {

    func setAnimatedProgress(progress: Float,
        duration: NSTimeInterval = 1,
        delay: NSTimeInterval = 0,
        completion: () -> ()
    ) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
            sleep(UInt32(delay))
            dispatch_async(dispatch_get_main_queue()) {
                self.layer.speed = Float(pow(duration, -1))
                self.setProgress(progress, animated: true)
            }
            sleep(UInt32(duration))
            dispatch_async(dispatch_get_main_queue()) {
                self.layer.speed = 1
                completion()
            }
        }
    }
}
Callam
  • 11,409
  • 2
  • 34
  • 32