nodyor90z nodyor90z - 6 months ago 13
Swift Question

the start button on my stopwatch resets the timer after stop has been activated swift

Why does the start button on my stopwatch resets the timer after stop has been pressed? Everything works fine until I stop the timer and then restart it. It should continue from the point where it was stopped but instead it resets the timer to 0. Here is my code:

class ViewController: UIViewController {

var timer = NSTimer()
var startTime = NSTimeInterval()

@IBOutlet var displayTimeLabel: UILabel!

@IBAction func start(sender: AnyObject) {

if !timer.valid {

timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: #selector(ViewController.updateTime), userInfo: nil, repeats: true)

}

startTime = NSDate.timeIntervalSinceReferenceDate()

}

@IBAction func stop(sender: AnyObject) {

timer.invalidate()
}

func updateTime() {

let currentTime = NSDate.timeIntervalSinceReferenceDate()
var elapsedTime: NSTimeInterval = currentTime - startTime

let hours = UInt8(elapsedTime / 3600)
elapsedTime -= (NSTimeInterval(hours) * 3600)

let minutes = UInt8(elapsedTime / 60)
elapsedTime -= (NSTimeInterval(minutes) * 60)

let seconds = UInt8(elapsedTime)
elapsedTime -= NSTimeInterval(seconds)

let fraction = UInt8(elapsedTime * 100)

let strHours = String(format: "%02d", hours)
let strMinutes = String(format: "%02d", minutes)
let strSeconds = String(format: "%02d", seconds)
let strFraction = String(format: "%02d", fraction)

displayTimeLabel.text = "\(strHours):\(strMinutes):\(strSeconds):\(strFraction)"

}

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}


}

Answer

You are setting your startTime each time the start method is called. You only want to do this the first time it is called. You can use optionals to determine the state correctly and only set the startTime when it is initially nil.

You could then create a reset button with a function that simply sets startDate = nil

class ViewController: UIViewController {

    var timer : NSTimer?
    var startTime? : NSTimeInterval?

    @IBOutlet var displayTimeLabel: UILabel!

    @IBAction func start(sender: AnyObject) {

        guard self.timer == nil else {
            return
        }

        if (self.startTime == nil) {
            self.startTime = NSDate.timeIntervalSinceReferenceDate()
        }

        self.timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: #selector(ViewController.updateTime), userInfo: nil, repeats: true)
    }

    @IBAction func stop(sender: AnyObject) {

        guard self.timer != nil else {
            return
        }

        self.timer!.invalidate()
        self.timer = nil
    }

    func updateTime() {

        let currentTime = NSDate.timeIntervalSinceReferenceDate()
        var elapsedTime: NSTimeInterval = currentTime - startTime!

        let hours = UInt8(elapsedTime / 3600)
        elapsedTime -= (NSTimeInterval(hours) * 3600)

        let minutes = UInt8(elapsedTime / 60)
        elapsedTime -= (NSTimeInterval(minutes) * 60)

        let seconds = UInt8(elapsedTime)
        elapsedTime -= NSTimeInterval(seconds)

        let fraction = UInt8(elapsedTime * 100)

        let timeString = String(format:"%02d:%02d:%02d.%02d",hours,minutes,seconds,fraction)
        displayTimeLabel.text = timeString

    }
}