Search code examples
iosswiftuiviewcontrollertimernstimer

Check for any timers running in any ViewController


I create and start a self-repeating timer in one of my ViewControllers (let's call it VC1) to have some kind of slideshow of images. When transitioning to any other VC the timer of VC1 appears to keep running as its selector method prints stuff every two seconds. Since this interferes with the timer when returning to VC1 from any other VC I have to remove it at some point.

This is what happens in the console: (runImages() is the timer's selector, the number is the image that should be displayed, as you see its weird...)

console output

  1. I thought the timer would stop once I exit VC1 since I do not save it anywhere. Since this is not the case I thought I might remove the timer when leaving VC1. Is there a method that is being called when VC1 is about to be dismissed?

  2. Another approach I had in mind was removing any timers at the beginning of source code of the other VCs. So, when I enter VC2 I want to check for any timers that are running in the project. Is there a way to do that without making the timer a global variable accessible to all VCs?

Code Reference

This is how I create the timer: (outside a method)

var timer: NSTimer!

Then, in a method I set it:

timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "runImages:", userInfo: nil, repeats: true)

runImage() then increases i and calls changeImage() which transitions my imageView's image to the image named like i.

Thanks in advance :)

Update

I made the timer a global variable that is accessible to every VC. The app starts up in VC1, then I transitioned to VC2. There, I inserted this code: if let t = timer {t.invalidate()} and if timer.valid {timer.invalidate()}. Now that made not difference, the timer's selector method keeps printing stuff...


Solution

  • you should keep a reference to the timer in the viewcontroller that is "using" it...

    class ViewController: UIViewController {
      var timer: NSTimer?
    
      override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
    
        timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: Selector("timerFired"), userInfo: nil, repeats: true)
      }
    
      func timerFired() {
        // do whatever you want
      }
    
      override func viewWillDisappear(animated: Bool) {
        if timer != nil {
          timer?.invalidate()
          timer = nil
        }
    
        super.viewWillDisappear(animated)
      }
    }