9

So I'm creating an app/game where you tap a button corresponding to a picture before the timer runs out and you lose. You get 1 second to tap the button, and if you choose the right button then the timer resets and a new picture comes up. I'm having trouble reseting the timer. It fires after one second even after I attempt to reset it. Here's the code:

loadPicture() runs off viewDidLoad()

func loadPicture() {
    //check if repeat picture
    secondInt = randomInt
    randomInt = Int(arc4random_uniform(24))
    if secondInt != randomInt {
        pictureName = String(self.PicList[randomInt])
        image = UIImage(named: pictureName)
        self.picture.image = image
        timer.invalidate()
        resetTimer()

    }
    else{
        loadPicture()
    }
}

and here's the resetTimer() method:

func resetTimer(){
        timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("gameOverTimer"), userInfo: nil, repeats: false)

}

I think it may have something to do with NSRunloops? I'm not sure. I don't even know what a NSRunloop is to be honest.

LuKenneth
  • 2,197
  • 2
  • 18
  • 41
  • I am not sure why your timer is firing after you invalidate it, but you have a bug in your recursion that checks for duplicates - You overwrite `randomInt` so that on the recursive call to `loadPicture` you are effectively checking if this random number is the same as the previous random number, not if this random number is the same as the previous picture that was displayed – Paulw11 Jul 29 '15 at 03:58
  • in loadPicture() before resetTimer() line write timer = nil . . . – iHardikTrivedi Jul 29 '15 at 04:03
  • To just make sure, are you creating the timer in same thread? second, did you try increasing the time out to say 5 seconds? – Shripada Jul 29 '15 at 05:19
  • Paulw11, There's no bug. The randomInt represents the index of the picture in the array. If the int is the same, the picture is the same too. – LuKenneth Jul 29 '15 at 18:35
  • iHart, that didn't work :( – LuKenneth Jul 29 '15 at 18:35
  • nshebbar, yes and yes – LuKenneth Jul 29 '15 at 18:35

1 Answers1

19

So I finally figured it out...

I had to make a separate function to start the timer by initializing it. And in the resetTimer() function I added the timer.invalidate() line. So my code looks like this:

func loadPicture() {
    //check if repeat picture
    secondInt = randomInt
    randomInt = Int(arc4random_uniform(24))
    if secondInt != randomInt {
        pictureName = String(self.PicList[randomInt])
        image = UIImage(named: pictureName)
        self.picture.image = image
        resetTimer()

    }
    else{
        loadPicture()
    }
}
func startTimer(){
    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("gameOverTimer"), userInfo: "timer", repeats: true)
}

func resetTimer(){

    timer.invalidate()
    startTimer()
}

EDIT

With the new selector syntax it looks like this:

func startTimer(){
    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(NameOfClass.startTimer), userInfo: "timer", repeats: true)
}
LuKenneth
  • 2,197
  • 2
  • 18
  • 41
  • `NSTimer.scheduledTimerWithTimeInterval` will give me back a new instance of NSTimer, right ? Is there any way to just reset the Timer, like, the same Timer instance ? – Que20 Dec 08 '16 at 15:45
  • no, i don't believe so. You can invalidate it, but if you do that you cannot start it back up again. @Que20 – LuKenneth Dec 08 '16 at 21:50