Как приостановить и возобновить NSTimer.scheduledTimerWithTimeInterval в swift?

Я разрабатываю игру и хочу создать меню паузы. Вот мой код:

self.view?.paused = true

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

Я хочу, чтобы time3 приостановил таймер, когда игрок щелкнул меню паузы, и продолжил запуск таймера, когда игрок вернулся в игру, но как я могу приостановить NSTimer.scheduledTimerWithTimeInterval? Помоги мне, пожалуйста.

Ответ 1

Вам необходимо аннулировать его и воссоздать. Затем вы можете использовать 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
    }
}

Ответ 2

Чтобы остановить его

  time3.invalidate() 

Чтобы запустить его снова

  time3.fire()

Ответ 3

Для начала:

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

Чтобы возобновить:

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

Пауза:

timer.invalidate

Это сработало для меня. Фокус в том, что не смотрите на что-то вроде "timer.resume" или "timer.validate". Просто используйте "тот же код для запуска таймера", чтобы возобновить его после паузы.

Ответ 4

Для запуска

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

Чтобы приостановить

timer.invalidate()

Кому reset

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

'label' - это таймер на выходе.

Ответ 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)
    }
}

Ответ 6

SWIFT3

Глобальная декларация:

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

viewDidLoad

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

Вызванный 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
      }                    
 }

Функция, которая обрабатывает вещи:

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

Таймер паузы: timer.invalidate()

и

Таймер возобновления: воссоздайте таймер. он отлично работает.

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

Ответ 8

Несмотря на то, что решения, представленные здесь, хороши, я думал, что важная проницательность отсутствует. Как и многие объясненные здесь люди, таймер invalidate() и воссоздание - лучший вариант. Но можно утверждать, что вы могли бы сделать что-то вроде этого:

var paused:Bool

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

проще реализовать, но он будет менее эффективным.

По соображениям влияния на энергию Apple рекомендует избегать таймеров, когда это возможно, и предпочитать уведомления о событиях. Если вам действительно нужно использовать таймер, вы должны эффективно выполнять паузы, недействив текущий таймер. Прочтите рекомендации по таймеру в Руководстве по энергоэффективности Apple: https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/MinimizeTimerUse.html

Ответ 9

Я просто работал над похожей проблемой с моей игрой и нашел простое решение.

Во-первых, я должен отметить, как и у других, что у Timer и NSTimer нет функции паузы. Вы должны остановить таймер с помощью Timer.invalidate(). После аннулирования таймера, вы должны инициализировать его снова, чтобы запустить таймер. Чтобы процитировать из https://developer.apple.com/documentation/foundation/timer, функцию .invalidate() -

Останавливает таймер от повторного срабатывания и запрашивает его удаление из цикла выполнения.


Чтобы приостановить таймер, мы можем использовать Timer.fireDate, именно здесь Timer (и 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)
}

Примечание: не аннулируйте() таймер до получения fireDate. После вызова invalidate() таймер сбрасывает fireDate на 2001-01-01 00:00:00 +0000.

2-е примечание: таймер может сработать после установленного fireDate. Это приведет к отрицательному числу, по умолчанию таймер будет работать через 0,1 миллисекунды. https://developer.apple.com/documentation/foundation/timer/1412416-scheduledtimer