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.
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
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