【问题标题】:Creating a countdown-timer(NSTimer) with milliseconds but it doesn't count down correctly用毫秒创建一个倒数计时器(NSTimer),但它不能正确倒数
【发布时间】:2016-02-23 18:55:11
【问题描述】:

我对 Xcode (swift) 很陌生,简而言之,我正在尝试制作一个以秒和小数倒计时的倒计时计时器。

它应该倒计时,但是,例如,当我从 13 秒开始倒计时时,手动计时时确实需要 23 秒。 这可能是一个简单的解决方案,但我尝试了很多东西,但无法弄清楚如何解决它。

这是我的代码:

 import UIKit

var timer = NSTimer()

var seconds = 13

var milliseconds = 0

class ViewController: UIViewController {

    @IBOutlet weak var Label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        Label.text = "\(seconds).\(milliseconds)"
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func Button(sender: AnyObject) {

        timer = NSTimer.scheduledTimerWithTimeInterval(0.001, target: self, selector: Selector("countDownfunction"), userInfo: nil, repeats: true)

    }


    func countDownfunction() {

        Label.text = "\(seconds).\(milliseconds)"

        if milliseconds == 0 {

            seconds -= 1
            milliseconds = 100
        } else {
            milliseconds -= 1
        }

    }

}

编辑:新代码仍然没有弄清楚,但我认为是正确的方式,我怎样才能像我一样减去/比较两个字符串:Label.text = (countdownSeconds - elapsedTime) 它给了我一个错误,我不能'-'两个字符串,我不知道如何比较两秒。谢谢

import UIKit

class ViewController: UIViewController {


@IBOutlet weak var Label: UILabel!

var startTime = NSDate.timeIntervalSinceReferenceDate()

var currentTime = NSDate.timeIntervalSinceReferenceDate()

var elapsedTime = String()

var differenceTime = String()

var countdownSeconds = String()


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}



@IBAction func Button(sender: AnyObject) {
    countdownSeconds = String(10)

    startTime = NSDate.timeIntervalSinceReferenceDate()

    NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("countDownUpdateMethod"), userInfo: nil, repeats: true)



}

func countDownUpdateMethod(){

    currentTime = NSDate.timeIntervalSinceReferenceDate()

    elapsedTime = String(currentTime - startTime )



    Label.text = (countdownSeconds - elapsedTime)



}



}

【问题讨论】:

  • NSTimer 的分辨率不够高

标签: ios swift nstimer countdown


【解决方案1】:

您忽略了安排和执行对countDownfunction 的调用的实际时间。 NSTimer 不会在 100 毫秒内给您回电,因为电话正在做其他事情。它根本不会那么准确。此外,countDownfunction 调用本身需要时间,而您没有考虑到这一点。

您应该通过记录开始时间并检查countDownfunction 中的当前时间来解决此问题,然后将两者相减以设置您的标签。这样可以补偿处理计时器的任何延迟。

您可以使用NSDate.timeIntervalSinceReferenceDate() 获取当前时间。

【讨论】:

  • @Josh 如果您满意,请接受答案,谢谢。
  • 是的,我会的,我忘记了,但我还没有完全弄清楚。 var Seconds 从 13 开始倒计时,那么当我将其与 NSDate.timeIntervalSinceReferenceDate() 进行比较以确保其时间正确时,我该怎么办?
  • 我还没有弄清楚我用新代码更新了帖子。 @EwanMellor
  • 不要尝试减去字符串。将所有变量声明为 NSTimeInterval (以秒为单位的浮点数)。用数字做所有的数学运算。仅在显示时转换为字符串,如 Label.text = String(amountOfTimeLeft)。
【解决方案2】:

您是否注意到您将毫秒设置为 100,而不是 1000?

因此,您的计时器在 23 秒内被调用了大约 1300 次。这听起来很对。是什么让您认为每秒倒数 1000 次是个好主意?人们看不到这一点。

如果您阅读了 NSTimer 的文档,重复计时器将尝试在预期时间触发(因此它们不会在最后一次触发后触发 X 秒,而是尝试在计时器触发后 X、2X、3X、4X 秒后触发已启动),但如果在给定时间内根本没有触发计时器,则丢弃该触发器。所以在 23 秒内你的计时器没有触发 23,000 次,而是 1300 次,正如人们所期望的那样。您不能每秒更新屏幕 1,000 次。如果可以的话,没人能看到。

以合理的速度运行您的计时器,每秒不超过 30 次,然后计算时间。不是基于倒计时,而是基于实际时间。

【讨论】:

  • 是的,你是对的,我没有注意到我的错误是 100 毫秒。但据我所知,NSTimer 不是很准确,所以我不想通过使用 NSDate.timeIntervalSinceReferenceDate() 来了解如何让它更准确。我确实用新代码更新了帖子你有时间检查一下吗?谢谢你。 @gnasher729
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多