How can I pause and resume NSTimer.scheduledTimerWithTimeInterval in swift?

I’m developing a game and I want to create a pause menu. Here is my code:

self.view?.paused = true

but NSTimer.scheduledTimerWithTimeInterval still running..

  • Underline part of a string using NSMutableAttributedString in iOS8 is not working
  • Reachability issue with iOS8
  • Swift : Extra Argument in call with scheduledTimerWithTimeInterval
  • Why use coreBluetooth connectPeripheral did not call delegate methods in IOS8
  • How do I export a public key <SecKey> that was generated using SecKeyGeneratePair to be used on a server?
  • Launch image or launch xib / storyboard?
  •  for var i=0; i < rocketCount; i++ {
     var a:NSTimeInterval = 1
     ii += a
     delaysShow =   2.0 + ((stimulus + interStimulus) * ii)       
     var time3 = NSTimer.scheduledTimerWithTimeInterval(delaysShow!, target: self, selector: Selector("showRocket:"), userInfo: rocketid[i]  , repeats: false)
     }
    

    I want time3 to pause the timer when player click pause menu and continue run the timer when player come back to the game, but how can I pause NSTimer.scheduledTimerWithTimeInterval? help me please.

    8 Solutions Collect From Internet About “How can I pause and resume NSTimer.scheduledTimerWithTimeInterval in swift?”

    You need to invalidate it and recreate it. You can then use an isPaused bool to keep track of the state if you have the same button to pause and resume the timer:

    var isPaused = true
    var timer = NSTimer()    
    @IBAction func pauseResume(sender: AnyObject) {     
        if isPaused{
            timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("somAction"), userInfo: nil, repeats: true)
            isPaused = false
        } else {
            timer.invalidate()
            isPaused = true
        }
    }
    

    To stop it

      time3.invalidate() 
    

    To start it again

      time3.fire()
    

    To Start:

    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("updateView"), userInfo: nil, repeats: true)
    

    To Resume:

    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("updateView"), userInfo: nil, repeats: true)
    

    To Pause:

    timer.invalidate
    

    This worked for me. The trick is that do not look for something like "timer.resume" or "timer.validate". Just use “the same code for starting a timer” to resume it after the pause.

    You can not resume the timer back.
    Instead of resuming – just create a new timer.

    class SomeClass : NSObject { // class must be NSObject, if there is no "NSObject" you'll get the error at runtime
    
        var timer = NSTimer()
    
        init() {
            super.init()
            startOrResumeTimer()
        }
    
        func timerAction() {
            NSLog("timer action")
        }
    
        func pauseTimer() {
            timer.invalidate
        }
    
        func startOrResumeTimer() {
            timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("timerAction"), userInfo: nil, repeats: true)
        }
    }
    

    To start

    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.action), userInfo: nil, repeats: true)
    

    To pause

    timer.invalidate()
    

    To reset

    time += 1
    label.text = String(time)
    

    ‘label’ is the timer on output.

    SWIFT3

    Global Declaration

     var swiftTimer = Timer()
     var count = 30
     var timer = Timer()
     @IBOutlet weak var CountDownTimer: UILabel!
    

    viewDidLoad

    override func viewDidLoad() {
    super.viewDidLoad()
    BtnStart.tag = 0
    }

    Triggered IBACTION

    @IBAction func BtnStartTapped(_ sender: Any) {
          if BtnStart.tag == 0 {
               BtnStart.setTitle("STOP", for: .normal)
               timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(ScoreBoardVC.update), userInfo: nil, repeats: true)
    
               BtnStart.tag = 1
          }
          else
          {
               BtnStart.setTitle("START", for: .normal)
               timer.invalidate()
    
               BtnStart.tag = 0
          }
    
    
     }
    

    Function that Handle The things

    func update(){
    
          if(count > 0){
               let minutes = String(count / 60)
               let ConvMin = Float(minutes)
               let minuttes1 = String(format: "%.0f", ConvMin!)
    
               print(minutes)
               let seconds = String(count % 60)
               let ConvSec = Float(seconds)
               let seconds1 = String(format: "%.0f", ConvSec!)
    
    
    
               CountDownTimer.text = (minuttes1 + ":" + seconds1)
               count += 1
          }
    
     }
    

    Pause timer : timer.invalidate()

    and

    Resume timer : recreate timer. it’s work fine.

    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(mainController.updateTimer), userInfo: nil, repeats: true)
    

    Even though the solutions exposed here are good, I thought an important insight was missing. Like a lot of people here explained, timer invalidate() and recreate is the best option. But one could argue that you could do something like this:

    var paused:Bool
    
    func timerAction() {
        if !paused {
            // Do stuff here
        }
    }
    

    is easier to implement, but it will be less efficient.

    For energy impact reasons, Apple promotes avoiding timers whenever possible and to prefer event notifications. If you really need to use a timer, you should implement pauses efficiently by invalidating the current timer. Read recommendations about Timer in the Apple Energy Efficiency Guide here:
    https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/MinimizeTimerUse.html