Search code examples
swiftprogress-barnstimeruiprogressviewnstimeinterval

Swift Progress View with NSTimer


I have a Progress view bar that I would like to use to indicate time. This is my first project in Swift, and I am unsure how to go about this. So any help/ advise would be appreciated ...

(Using Xcode 7.2 and Swift 2.0)

Below Is my view controller. When 'btnPlaySession' is triggered, the content on the view controller is changed every 20 seconds. While the timer is counting to 20, id like to indicate this with the progress bar (so the progress bar resets, each time the content changes).

class CreatedSessionViewController: UIViewController {

var createdSession: [YogaPose]!
var poseDuration: Double = 20.00 
var timer = NSTimer!()
var currentPoseIndex = 1

//Outlets:
@IBOutlet var poseProgressView: UIProgressView!
@IBOutlet var lblPoseCount: UILabel!
@IBOutlet var lblPoseName: UILabel!
@IBOutlet var imgPose: UIImageView!
@IBOutlet var tvDescription: UITextView!

// Do any additional setup after loading the view:
override func viewDidLoad() {
    super.viewDidLoad()

    displayFirstPoseInArray()
}

func displayFirstPoseInArray(){
    lblPoseCount.text = (String(currentPoseIndex) + "/" + String(createdSession.count))
    lblPoseName.text = createdSession[0].title
    imgPose.image = UIImage(named: String(format: "%d.jpg", (createdSession[0].id)!))
    tvDescription.text = createdSession[0].desc
}

@IBAction func btnPlaySession(sender: AnyObject) {
    timer = NSTimer.scheduledTimerWithTimeInterval(poseDuration, target: self, selector: "getNextPoseData", userInfo: nil, repeats: true)
}

func getNextPoseData(){
    if (currentPoseIndex < createdSession.count){

        setProgressBar()

        lblPoseCount.text = (String(currentPoseIndex + 1) + "/" + String(createdSession.count))
        lblPoseName.text = createdSession[currentPoseIndex].title
        imgPose.image = UIImage(named: String(format: "%d.jpg",(createdSession[currentPoseIndex].id)!))
        tvDescription.text = createdSession[currentPoseIndex].desc
        currentPoseIndex += 1
        print(currentPoseIndex)
    }
}

func setProgressBar(){


}
}

Solution

  • OK - so if you want the progress bar to update every second, then you need a timer that fires every second - but which does it 20 times, and calls setProgressBar as selector instead of getNextPoseData

    within setProgressBar, you need to increment a class-level attribute, indexProgressBar perhaps, and simply set the progress bar attribute progress to 1.0 / indexProgressBar

    if indexProgressBar == 20, then call getNextPoseData, and reset your progress bar

    and here's a simplified version of how you might do that

    class ViewController: UIViewController
    {
        @IBOutlet weak var progressBar: UIProgressView!
        var timer = NSTimer!()
        var poseDuration = 20
        var indexProgressBar = 0
        var currentPoseIndex = 0
    
        override func viewDidLoad()
        {
            super.viewDidLoad()
    
            // initialise the display
            progressBar.progress = 0.0
        }
    
    
        @IBAction func cmdGo(sender: AnyObject)
        {
            // display the first pose
            getNextPoseData()
    
            // start the timer
            timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "setProgressBar", userInfo: nil, repeats: true)
        }
    
        func getNextPoseData()
        {
            // do next pose stuff
            currentPoseIndex += 1
            print(currentPoseIndex)
        }
    
        func setProgressBar()
        {
            if indexProgressBar == poseDuration
            {
                getNextPoseData()
    
                // reset the progress counter
                indexProgressBar = 0
            }
    
            // update the display
            // use poseDuration - 1 so that you display 20 steps of the the progress bar, from 0...19
            progressBar.progress = Float(indexProgressBar) / Float(poseDuration - 1)
    
            // increment the counter
            indexProgressBar += 1
        }
    }