2016-06-26 5 views
0

Ich versuche, genaue Zählung und Anzeige eines Countdown-Timers zwischen Switching View-Controller zu halten. Um dies zu tun, habe ich NSNotifications wie in dieser Frage erwähnt hinzugefügt: Timer Label not updated after switching views (swift)NSTimer zweimal ausgelöst nach dem Umschalten der Ansicht Controller

Das Problem ist, dass der Timer zweimal nach dem Zurückschalten von der anderen Ansicht Controller dekrementiert wird. Dieses Problem scheint nichts mit den Benachrichtigungen zu tun zu haben, da das gleiche Problem ohne sie auftritt. Es wird erst nach dem Neustart des Timers sichtbar, da es beim Erreichen des View-Controllers nicht automatisch aktualisiert wird.

Ich finde wirklich nicht die Ursache dafür, jede Hilfe sehr geschätzt!

Ich habe diesen Beispielcode eingerichtet. Es gibt einen weiteren View-Controller, der zum ursprünglichen in Main.storyboard hinzugefügt wurde. Es gibt einen Switch und ein Label, auf dem der hinzugefügte Timer angezeigt wird. Der ursprüngliche Ansichts-Controller enthält nur einen Balkenschaltknopf, um den Übergang zum zweiten Ansichts-Controller auszulösen.

import Foundation 

final class DataModel: NSObject { 

    static let shared = DataModel() 

    var isSleepTimerOn = false 
    var timerTime: NSTimeInterval = 100.0 

} 

// The second view controller. 

import UIKit 

class TimerViewController: UIViewController { 

    @IBOutlet weak var timerLabel: UILabel! 
    @IBOutlet weak var timerSwitch: UISwitch! 

    var timer: NSTimer? 

    override func viewDidLoad() { 
    super.viewDidLoad() 

    timerSwitch.on = DataModel.shared.isSleepTimerOn 
    timerLabel.text = String(DataModel.shared.timerTime) 

    let selector = #selector(setTimerLabel), name = "setTimerLabel" 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: selector, name: name, object: nil) 
    } 

    @IBAction func switchToggled(sender: AnyObject) { 
    DataModel.shared.isSleepTimerOn = timerSwitch.on 

    switch timerSwitch.on { 
    case true: 
     startTimer() 
    case false: 
     stopTimer() 
    } 
    } 

    func startTimer() { 
    let selector = #selector(decrementTimer) 
    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: selector, userInfo: nil, repeats: true) 
    NSRunLoop.mainRunLoop().addTimer(timer!, forMode: NSRunLoopCommonModes) 
    } 

    func decrementTimer() { 
    DataModel.shared.timerTime -= 1 
    NSNotificationCenter.defaultCenter().postNotificationName("setTimerLabel", object: nil) 

    setTimerLabel() 
    } 

    func setTimerLabel() { 
    timerLabel.text = String(DataModel.shared.timerTime) 
    } 

    func stopTimer() { 
    timer?.invalidate() 
    timer = nil 

    DataModel.shared.timerTime = 100.0 
    timerLabel.text = String(DataModel.shared.timerTime) 

    NSNotificationCenter.defaultCenter().removeObserver(self, name: "setTimerLabel", object: nil) 
    } 

} 

EDIT: Lösung: der Timer aus der View-Controller-Klasse, um das Datamodel Singleton bewegen, so würde es nur ein Timer sein.

+1

Ich habe vor kurzem einen Timer gebaut, den ich wollte egal was. Ich habe einen String aus einem NSDate erstellt, den ich in CoreData gespeichert habe, als ich den Timer gestartet habe. Dann würde ich diese Zeichenfolge mit einem Getter abrufen, der sie zurück in ein NSDate verwandelt. Ich würde dann ein Zeitintervall zwischen diesem Datum und dem aktuellen Datum machen. Zuletzt würde ich prüfen, ob die Gesamtlänge des Timers - das Zeitintervall, das ich gerade gemacht habe,> 0 war. Wenn das der Fall war, habe ich den Timer mit dem Wert> 0 neu gestartet, bis der Benutzer die Ansicht sehen konnte auf. Mit dieser Methode wird garantiert, dass Ihre verbleibende Zeit stimmt. – Sethmr

+0

Vielen Dank für den Vorschlag, Sethmr, ich werde das nächste Mal auf jeden Fall versuchen, es scheint irgendwie Overkill in meiner Situation zu sein, wo ich im Grunde nur einen Schlaf-Timer brauche. Ich würde immer noch gerne den Fehler im obigen Code finden, wenn jemand weiß ...! – nontomatic

Antwort

1

Ok, neuer Morgen, frisches Gehirn, hatte einen anderen Blick auf den Code und das Problem war klar: Ich startete einen neuen Timer jedes Mal, wenn ich auf den View-Controller wechselte, also wenn der Timer gestoppt wurde, würde es nicht aufhören Der vorherige. Da es nur einen Timer geben sollte, habe ich ihn aus der View-Controller-Klasse in das DataModel verschoben, das ein Singleton ist.

Verwandte Themen