Swift Timer Problems

sw2037122

I'm doing a game in which there are many rounds, and each round, the timer resets to zero. This is my code for when I get it correct:

func correct() {
    time = 10
    timer()
    //bla bla bla
}

And this is the code for the timer:

func timer() {
    let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
    dispatch_after(delayTime, dispatch_get_main_queue()) {
        self.time -= 1
        if self.time > 0 {
            self.timer()
        } else {
            self.dismissViewControllerAnimated(true, completion: nil)
        }
    }

}

I had expected the timer to reset to 10 and tick every second normally, but instead, it went back to ten, but it was counting down really quickly. For example, by round three, it was counting like 10, 9, 7, 6, and each number only lasted about half a second. Can you please tell me how to fix it if possible please? Thanks!

UPDATE: Apparently, my problem was that I was running multiple timers at once. I need be able to replace the original timer with the new one, or at least stop the original. I've searched it up and found .invalidate(), but I'm not sure how to use it. If that's the method I should use, then how should I use it? Thanks!

Sulthan

There are various ways to do what you want to do, using a NSTimer is probably the best solution. You can use either a repeating timer (will be invoked repeatedly after an interval) or one without repeating (you will have to reschedule it for every iteration).

The bonus of using a timer instead of dispatch_after is the fact that you can easily cancel (invalidate) a timer, thus avoiding conflicting timers.

Using a timer without repeating:

var timer: NSTimer?
var time: Int = 0

func correct() {
    time = 10

    //this will remove the previous timer
    timer?.invalidate()
    startTimer()
}

func startTimer() {
    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "onTimerFired", userInfo: nil, repeats: false)
}

func onTimerFired() {
    time -= 1

    if self.time > 0 {
        startTimer()
    } else {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}

Using a timer with repeating:

var timer: NSTimer?
var time: Int = 0

func correct() {
    time = 10

    //this will remove the previous timer
    timer?.invalidate()
    startTimer()
}

func startTimer() {
    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "onTimerFired", userInfo: nil, repeats: true)
}

func onTimerFired() {
    time -= 1

    if time == 0 {
        //need to remove the timer here otherwise it would keep repeating
        timer!.invalidate()
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}

Of course, you can also just use the already running timer, just check if timer != nil && timer!.valid and don't start a new one if the condition is true.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related