2017-10-17 8 views
0

Ich möchte diesen Timer stoppen und starten Sie es dann von wo ich es gestoppt habe.Stoppen und starten Sie einen Timer

secondsTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(addSeconds), userInfo: nil, repeats: true) 

Im Folgenden wurde vorgeschlagen, ich soll nicht einen Timer in meinem Timer-Handler erhöhen. Warum nicht?

Zum Beispiel mit GCD-Timer:

func countSeconds() { 

    secondsTimer = DispatchSource.makeTimerSource(queue: .main) 
    secondsTimer?.schedule(deadline: .now(), repeating: 1.0) 

    secondsTimer?.setEventHandler { [weak self] in 

     self?.addSeconds() 
    } 
} 

@objc func addSeconds() { 
    seconds += 1       
} 

func startGame() { 
    secondsTimer?.resume() 
} 

Antwort

0

Wir pausieren nicht/Timer Instanzen fortzusetzen. Wir stoppen sie mit . Und wenn Sie es neu starten möchten, erstellen Sie einfach einen neuen Timer.

Bitte beziehen Sie sich auf the Timer documentation, auch verfügbar in Xcode.


Hinweis, dass man suspend und resume GCD Timer, DispatchSourceTimer.

var timer: DispatchSourceTimer? // note, unlike `Timer`, we have to maintain strong reference to GCD timer sources 

func createTimer() { 
    timer = DispatchSource.makeTimerSource(queue: .main) 
    timer?.schedule(deadline: .now(), repeating: 1.0) 

    timer?.setEventHandler { [weak self] in  // assuming you're referencing `self` in here, use `weak` to avoid strong reference cycles 
     // do something 
    } 

    // note, timer is not yet started; you have to call `timer?.resume()` 
} 

func startTimer() { 
    timer?.resume() 
} 

func pauseTiemr() { 
    timer?.suspend() 
} 

func stopTimer() { 
    timer?.cancel() 
    timer = nil 
} 

Bitte beachten Sie, ich sage nicht, dass, wenn Sie wollen suspend und resume, die Sie DispatchSourceTimer GCD nutzen sollten. Rufen Sie einfach an und erstellen Sie Timer nach Bedarf. Das ist einfach genug. Ich gebe diese GCD-Informationen nur der Vollständigkeit halber an.


Übrigens, als einen allgemeinen Grundsatz, nie "Zähler" in Ihrem Timer-Handler "inkrementieren". Das ist ein häufiger Anfängerfehler. Timer sind nicht garantiert, um jedes Mal oder mit der genauen Präzision zu schießen. Speichern Sie immer eine Referenzzeit am Anfang, und berechnen Sie dann in Ihrem Event-Handler Unterschiede zwischen der aktuellen Uhrzeit und der Startzeit. Zum Beispiel, mein GCD-Timer-Beispiel zu erweitern:

func createTimer() { 
    timer = DispatchSource.makeTimerSource(queue: .main) 
    timer?.schedule(deadline: .now(), repeating: 0.1) 

    let formatter = DateComponentsFormatter() 
    formatter.unitsStyle = .positional 
    formatter.allowedUnits = [.hour, .minute, .second, .nanosecond] 
    formatter.zeroFormattingBehavior = .pad 

    timer?.setEventHandler { [weak self] in 
     guard let start = self?.start else { return } 
     let elapsed = (self?.totalElapsed ?? 0) + CACurrentMediaTime() - start 
     self?.label.text = formatter.string(from: elapsed) 
    } 
} 

var start: CFTimeInterval?   // if nil, timer not running 
var totalElapsed: CFTimeInterval? 

@objc func didTapButton(_ button: UIButton) { 
    if start == nil { 
     startTimer() 
    } else { 
     pauseTimer() 
    } 
} 

private func startTimer() { 
    start = CACurrentMediaTime() 
    timer?.resume() 
} 

private func pauseTimer() { 
    timer?.suspend() 
    totalElapsed = (totalElapsed ?? 0) + (CACurrentMediaTime() - start!) 
    start = nil 
} 
+0

Und wie kann ich einen Sekundenzähler erstellen, wo ich es stoppen und fortsetzen kann? Vielen Dank –

+0

Erfassen Sie die Startzeit ('CACurrentMediaTime()' oder 'CFAbsoluteTimeGetCurrent()'), wenn Sie einen Timer starten und wenn Sie den Timer anhalten, berechnen Sie die verstrichene Zeit zwischen 'CACurrentMediaTime()' oder 'CFAbsoluteTimeGetCurrent()' und gespeicherte Startzeit – Rob

+0

Ich verstehe nicht, können Sie mir mit Code helfen? –

Verwandte Themen