【问题标题】:NSTimer triggered twice after switching view controllersNSTimer 切换视图控制器后触发两次
【发布时间】:2016-06-26 20:01:55
【问题描述】:

我试图在切换视图控制器之间保持准确的计数和倒数计时器的显示。为此,我添加了此问题中提到的 NSNotifications:Timer Label not updated after switching views (swift)

问题是从另一个视图控制器切换回来后,计时器将递减两次。 这个问题似乎与通知无关,因为没有通知也会出现同样的问题,只有在重新启动计时器后才会变得明显,因为到达视图控制器时它不会自动更新。

我真的找不到原因,非常感谢任何帮助!

我已经设置了这个示例代码。在 Main.storyboard 的原始视图控制器中添加了另一个视图控制器,有一个开关和一个显示添加到其中的计时器的标签。原始视图控制器仅包含一个条形按钮项来触发到第二个视图控制器的 segue。

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)
  }

}

编辑:解决方案:将计时器从视图控制器类移动到 DataModel 单例,这样就只有一个计时器。

【问题讨论】:

  • 我最近建立了一个计时器,无论如何我都想坚持下去。当我启动计时器时,我制作了一个存储在 CoreData 中的 NSDate 字符串。然后我会用一个吸气剂检索那个字符串,把它变成一个 NSDate。然后我会在那个日期和当前日期之间做一个时间间隔。最后,我会检查计时器的总长度是否 - 我刚刚制作的时间间隔 > 0。如果是这种情况,我会以 > 0 的任何数量重新启动计时器,直到它完成,然后用户才能看到它的视图上。使用这种方法可以保证你的剩余时间是准确的。
  • 非常感谢 Sethmr 的建议,下次我一定会尝试这种方法,在我基本上只需要一个睡眠定时器的情况下,这似乎有点矫枉过正。我仍然想在上面的代码中找到错误,所以如果有人知道......!

标签: ios swift nstimer nsnotification


【解决方案1】:

好的,新的早晨,新鲜的大脑,再看一下代码,问题就很清楚了:我每次切换到视图控制器时都在启动一个新的计时器,所以当停止计时器时,它不会停止前一个。因为应该只有一个计时器,所以我将它从视图控制器类移到了 DataModel,它是一个单例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多