Ios 使用Swift的计时器只能倒计时20秒,而不是20分钟

Ios 使用Swift的计时器只能倒计时20秒,而不是20分钟,ios,swift,nstimer,Ios,Swift,Nstimer,我在我的iOS应用程序上创建了一个计时器,从20分钟倒计时到0秒,一次倒计时一秒。到目前为止,计时器工作,但只倒计时20秒,而不是分钟。当它达到零时,它也不会停止。如何解决这个问题 import UIKit class SkippingViewController: UIViewController { @IBOutlet weak var timeLabel: UILabel! @IBOutlet weak var startWorkoutButton: UIButton!

我在我的iOS应用程序上创建了一个计时器,从20分钟倒计时到0秒,一次倒计时一秒。到目前为止,计时器工作,但只倒计时20秒,而不是分钟。当它达到零时,它也不会停止。如何解决这个问题

import UIKit

class SkippingViewController: UIViewController {
    @IBOutlet weak var timeLabel: UILabel!
    @IBOutlet weak var startWorkoutButton: UIButton!
    @IBOutlet weak var pauseWorkoutButton: UIButton!

    var timer = Timer()
    var counter = 20.00
    var isRunning = false

    override func viewDidLoad() {
        super.viewDidLoad()

        timeLabel.text = "\(counter)"
        startWorkoutButton.isEnabled = true
        pauseWorkoutButton.isEnabled = false
    }

    @IBAction func startWorkoutButtonDidTouch(_ sender: Any) {
        if !isRunning {
            timer = Timer.scheduledTimer(timeInterval: -0.01, target: self, selector: #selector(SkippingViewController.updateTimer), userInfo: nil, repeats: true)

            startWorkoutButton.isEnabled = false
            pauseWorkoutButton.isEnabled = true
            isRunning = true
        }
    }

    @IBAction func pauseWorkoutButtonDidTouch(_ sender: Any) {
        startWorkoutButton.isEnabled = true
        pauseWorkoutButton.isEnabled = false

        timer.invalidate()
        isRunning = false
    }

    @objc func updateTimer() {
        counter -= 0.01
        timeLabel.text = String(format: "%.01f", counter)
    }


我发现您的代码中有几个问题妨碍了它按您希望的方式工作

首先,如果在
scheduledTimer
方法中传递的
timeInterval
为负,则始终会创建一个每隔0.1毫秒触发一次的计时器(源:)

您希望每秒调用
updateTimer
,因此只需将1.0传递给
scheduledTimer
方法,例如:

timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(SkippingViewController.updateTimer), userInfo: nil, repeats: true)
此外,您希望在启动计时器20分钟后使该计时器无效。因此,在设置计时器时,您可以跟踪当前时间,并且当该时间+20分钟超过在
updateTimer
中调用时的当前时间时,您可以使计时器无效。换句话说,我们不是从20分钟开始倒数,而是从0开始倒数,直到20分钟过去

示例代码(没有尝试编译它,但应该可以工作,如果不行请告诉我):

请注意,我还用
timer.isValid
替换了您添加的
isRunning
var,因为我相信它将在不引入其他变量的情况下实现同样的效果


唯一可能剩下的是关于您正在显示的标签的文本。我不确定你到底想在这里展示什么。如果您可以在评论中添加这一点,我可以建议一种方法。

我看到您的代码存在一些问题,这些问题阻碍了它按照您想要的方式工作

首先,如果在
scheduledTimer
方法中传递的
timeInterval
为负,则始终会创建一个每隔0.1毫秒触发一次的计时器(源:)

您希望每秒调用
updateTimer
,因此只需将1.0传递给
scheduledTimer
方法,例如:

timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(SkippingViewController.updateTimer), userInfo: nil, repeats: true)
此外,您希望在启动计时器20分钟后使该计时器无效。因此,在设置计时器时,您可以跟踪当前时间,并且当该时间+20分钟超过在
updateTimer
中调用时的当前时间时,您可以使计时器无效。换句话说,我们不是从20分钟开始倒数,而是从0开始倒数,直到20分钟过去

示例代码(没有尝试编译它,但应该可以工作,如果不行请告诉我):

请注意,我还用
timer.isValid
替换了您添加的
isRunning
var,因为我相信它将在不引入其他变量的情况下实现同样的效果


唯一可能剩下的是关于您正在显示的标签的文本。我不确定你到底想在这里展示什么。如果您可以在评论中添加这一点,我可以建议一种方法。

您已将计时器的间隔设置为每0.01秒启动一次,即每秒100次。每次您都将
计数器调整0.01。这意味着它将以每秒1的速率递减
计数器。因此,
20的
计数器将在20秒后过期,而不是20分钟。如果您想要20分钟使用计数器机制,您可以使用
20*60


还有几个其他的观察结果:

  • 定时器不能保证按要求的间隔开火。保存倒计时的时间(或开始倒计时的时间)并计算从倒计时到倒计时所经过的时间更安全。然后,您可以用一个漂亮的字符串表示所经过的时间来更新标签

  • 你每百分之一秒就启动一次计时器。但屏幕通常不会以这种频率更新。除此之外,你只显示了几分钟和几秒钟,因此更频繁地更新并没有什么好处

    但是,如果我显示毫秒,并且想要一个最佳的计时器频率,我会使用一个而不是一个计时器。而且,根据上面第1点的精神,如果您使用“开始”/“停止”日期来计算经过的时间,而不是计数器,那么您不必担心刷新率是多少,因为我们不再递减计数器


  • 您已将计时器的间隔设置为每0.01秒启动一次,即每秒100次。每次您都将
    计数器调整0.01。这意味着它将以每秒1的速率递减
    计数器。因此,
    20的
    计数器将在20秒后过期,而不是20分钟。如果您想要20分钟使用计数器机制,您可以使用
    20*60


    还有几个其他的观察结果:

  • 定时器不能保证按要求的间隔开火。保存倒计时的时间(或开始倒计时的时间)并计算从倒计时到倒计时所经过的时间更安全。然后,您可以用一个漂亮的字符串表示所经过的时间来更新标签

  • 你每百分之一秒就启动一次计时器。但屏幕通常不会以这种频率更新。除此之外,你只显示了几分钟和几秒钟,因此更频繁地更新并没有什么好处

    但是,如果我显示毫秒,并且想要一个最佳的计时器频率,我会使用一个而不是一个计时器。而且,根据上面第1点的精神,如果您使用“开始”/“停止”日期来计算经过的时间,而不是计数器,那么您不必担心刷新率是多少,因为我们不再递减计数器


  • 为什么您希望计时器停止在0?您没有停止计时器的代码。修复格式:使用
    “%.2f”
    。为什么需要计时器