如何在swift中暂停和恢复NSTimer.scheduledTimerWithTimeInterval?

Pan*_*ian 20 nstimer swift ios8

我正在开发一款游戏,我想创建一个暂停菜单.这是我的代码:

self.view?.paused = true
Run Code Online (Sandbox Code Playgroud)

但是NSTimer.scheduledTimerWithTimeInterval仍在运行..

 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)
 }
Run Code Online (Sandbox Code Playgroud)

我希望time3在玩家点击暂停菜单时暂停计时器并在玩家回到游戏时继续运行计时器,但我怎么能暂停NSTimer.scheduledTimerWithTimeInterval?请帮帮我.

jon*_*nie 35

您需要使其无效并重新创建它.isPaused如果您有相同的按钮可以暂停和恢复计时器,则可以使用bool跟踪状态:

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
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 10

我刚刚在游戏中解决了类似的问题,并找到了一个简单的解决方案。

首先我应该像其他人一样指出,Timer 和 NSTimer 没有暂停功能。您必须使用 Timer.invalidate() 停止计时器。使Timer失效后,必须重新初始化才能启动Timer。引用https://developer.apple.com/documentation/foundation/timer,函数 .invalidate() -

停止计时器再次触发并请求将其从运行循环中删除。


要暂停计时器,我们可以使用 Timer.fireDate,这是计时器(和 NSTimer)保存计时器将来触发的日期的地方。

以下是我们如何通过保存计时器再次触发之前剩余的秒数来暂停计时器。

//The variable we will store the remaining timers time in
var timeUntilFire = TimeInterval()

//The timer to pause
var gameTimer = Timer.scheduledTimer(timeInterval: delaysShow!, target: self, selector: #selector(GameClass.showRocket), userInfo: rocketid[i], repeats: false)

func pauseTimer()
{
    //Get the difference in seconds between now and the future fire date
    timeUntilFire = gameTimer.fireDate.timeIntervalSinceNow
    //Stop the timer
    gameTimer.invalidate()
}

func resumeTimer()
{
    //Start the timer again with the previously invalidated timers time left with timeUntilFire
    gameTimer = Timer.scheduledTimer(timeInterval: timeUntilFire, target: self, selector: #selector(GameClass.showRocket), userInfo: rocketid[i], repeats: false)
}
Run Code Online (Sandbox Code Playgroud)

注意:在获取 fireDate 之前不要使 Timer 无效。调用 invalidate() 后,计时器似乎将 fireDate 重置为 2001-01-01 00:00:00 +0000。

第二个注意事项:计时器可能会在其设置的 fireDate 之后触发。这将导致负数,这将默认计时器在 0.1 毫秒后运行。https://developer.apple.com/documentation/foundation/timer/1412416-scheduledtimer


Chr*_*cou 6

阻止它

  time3.invalidate() 
Run Code Online (Sandbox Code Playgroud)

再来一次

  time3.fire()
Run Code Online (Sandbox Code Playgroud)

  • 来自Apple文档:"(invalidate)停止接收器再次触发并请求从其运行循环中删除它." 一旦调用invalidate,您应该将计时器设置为nil并且(重新)实例化/再次触发"重启". (10认同)
  • `.fire()` 不会再次启动计时器(从某种意义上说,它将继续重复对选择器的调用。)为了做到这一点(这就是OP所说的“恢复”的意思),你必须重新初始化定时器。 (2认同)

Bil*_*ack 5

开始:

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

恢复:

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

暂停:

timer.invalidate
Run Code Online (Sandbox Code Playgroud)

这对我有用。诀窍是不要寻找类似"timer.resume"或的东西"timer.validate"。只需在暂停后使用“用于启动计时器的相同代码”来恢复它即可。


nic*_*zzz 5

您无法恢复计时器。无需恢复 - 只需创建一个新计时器即可。

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)
    }
}
Run Code Online (Sandbox Code Playgroud)


Kay*_*Cee 5

开始

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

暂停

timer.invalidate()
Run Code Online (Sandbox Code Playgroud)

重置

time += 1
label.text = String(time)
Run Code Online (Sandbox Code Playgroud)

“标签”是输出中的计时器。