Я пытаюсь сохранить точный подсчет и отображение таймера обратного отсчета между переключающими диспетчерами. Для этого я добавил NSNotifications, как указано в этом вопросе: Timer Label not updated after switching views (swift)NSTimer запускается дважды после переключения диспетчеров отображения
Проблема в том, что таймер будет уменьшаться дважды после переключения с другого контроллера вида. Эта проблема, по-видимому, не связана с уведомлениями, поскольку такая же проблема возникает без них, она становится очевидной только после перезапуска таймера, поскольку она не обновляется автоматически при достижении контроллера вида.
Я действительно не могу найти причину этого, любую помощь очень ценю!
Я установил этот пример кода. Есть еще один контроллер представления, добавленный к оригиналу в Main.storyboard, есть один переключатель и одна метка, отображающая добавленный к нему таймер. В исходном контроллере представлений содержится только один элемент кнопки «бар», чтобы вызвать переход к второму контроллеру представления.
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: Решение: переместите таймер из класса контроллера представления в DataModel одноточечного, так что будет только один таймер.
Недавно я построил таймер, который я хотел сохранить, несмотря ни на что. Я создал строку NSDate, которую я сохранил в CoreData, когда я запустил таймер. Затем я бы извлек эту строку, когда геттер вернул ее в NSDate. Затем я сделаю временной интервал между этой датой и текущей датой. Наконец, я бы проверил, была ли общая длина таймера - только что сделанный промежуток времени был> 0. Если это было так, я перезапустил таймер с любой суммой, которая была> 0, пока она не завершится до того, как пользователь увидит представление, которое оно было на. Использование этого метода гарантирует, что ваше время остается точным. – Sethmr
Большое спасибо за предложение Sethmr, я обязательно попробую этот подход в следующий раз, он вроде бы кажется излишним в моей ситуации, когда мне в основном нужен таймер сна. Мне все равно хотелось бы найти ошибку в коде выше, поэтому, если кто-нибудь знает ...! – nontomatic