web-dev-qa-db-ja.com

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?お願い助けて。

19

無効にしてから再作成する必要があります。その後、タイマーを一時停止および再開するための同じボタンがある場合、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
    }
}
35
jonnie

止めるために

  time3.invalidate() 

もう一度起動するには

  time3.fire()

始めること

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

一時停止する

timer.invalidate()

リセットするには

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

「ラベル」は出力時のタイマーです。

5
Kay Cee

始めること:

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

これは私のために働いた。秘Theは、"timer.resume""timer.validate"のようなものを探しないことです。 "タイマーを開始するための同じコード"を使用して、一時停止後に再開します。

タイマーを再開することはできません。再開する代わりに、新しいタイマーを作成してください。

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

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

私は自分のゲームで同様の問題に取り組んでいたところ、簡単な解決策を見つけました。

最初に、他の人が持っているように、タイマーと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を取得する前にTimerを無効にしないでください。 invalidate()が呼び出された後、タイマーはfireDateを2001-01-01 00:00:00 +0000にリセットするようです。

2番目の注:タイマーは、設定されたfireDateの後に発火する可能性があります。これにより、負の数になり、タイマーはデフォルトで0.1ミリ秒後に実行されます。 https://developer.Apple.com/documentation/foundation/timer/1412416-scheduledtimer

1
stelf

ここで公開されているソリューションは優れていますが、重要な洞察が欠けていると思いました。ここで多くの人が説明したように、タイマーのinvalidate()と再作成が最適なオプションです。しかし、次のようなことができると主張することができます:

var paused:Bool

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

実装は簡単ですが、効率は低下します。

エネルギーへの影響の理由から、Appleは可能な限りタイマーを避け、イベント通知を優先するように促進します。本当に使用する必要がある場合タイマーの場合、現在のタイマーを無効にすることで効率的に一時停止を実装する必要があります。タイマーについての推奨事項は、Apple Energy Efficiency Guide here: https://developer.Apple.com/library /content/documentation/Performance/Conceptual/EnergyGuide-iOS/MinimizeTimerUse.html

0

一時停止タイマー:timer.invalidate()

そして

タイマーを再開:タイマーを再作成します。うまくいきました。

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