2016-06-26 4 views
0

Я пытаюсь сохранить точный подсчет и отображение таймера обратного отсчета между переключающими диспетчерами. Для этого я добавил 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 одноточечного, так что будет только один таймер.

+1

Недавно я построил таймер, который я хотел сохранить, несмотря ни на что. Я создал строку NSDate, которую я сохранил в CoreData, когда я запустил таймер. Затем я бы извлек эту строку, когда геттер вернул ее в NSDate. Затем я сделаю временной интервал между этой датой и текущей датой. Наконец, я бы проверил, была ли общая длина таймера - только что сделанный промежуток времени был> 0. Если это было так, я перезапустил таймер с любой суммой, которая была> 0, пока она не завершится до того, как пользователь увидит представление, которое оно было на. Использование этого метода гарантирует, что ваше время остается точным. – Sethmr

+0

Большое спасибо за предложение Sethmr, я обязательно попробую этот подход в следующий раз, он вроде бы кажется излишним в моей ситуации, когда мне в основном нужен таймер сна. Мне все равно хотелось бы найти ошибку в коде выше, поэтому, если кто-нибудь знает ...! – nontomatic

ответ

1

Хорошо, новое утро, свежий мозг, еще раз посмотрел на код, и проблема была ясна: я запускал новый таймер каждый раз, когда я переключался на контроллер вида, поэтому, останавливая таймер, он не останавливался предыдущий. Поскольку должен быть только один таймер, я переместил его из класса контроллера вида в DataModel, который является одноэлементным.

Смежные вопросы