How can I pause and resume NSTimer.scheduledTimerW

2019-01-18 22:22发布

问题:

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..

 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.

回答1:

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
    }
}


回答2:

To stop it

  time3.invalidate() 

To start it again

  time3.fire()


回答3:

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.



回答4:

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.



回答5:

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)
    }
}


回答6:

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
      }

 }


回答7:

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)


回答8:

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