使用 NSTimer 仅以秒为单位倒计时(从 00:20 到 0)

Countdown in seconds only (form 00:20 to 0) using NSTimer

我需要一个从 20 秒到 0 的标签倒计时,然后重新开始。这是我第一次在 Swift 做项目,我正在尝试使用 NSTimer.scheduledTimerWithTimeInterval。此倒计时应 运行 循环给定次数。

我很难实现 StartStart again 方法(循环)。我基本上找不到一种方法来启动时钟 20 秒,当它结束时,再次启动它。

如果有任何关于如何做到这一点的想法,我将不胜感激 瓦格纳

 @IBAction func startWorkout(sender: AnyObject) {

    timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("countDownTime"), userInfo: nil, repeats: true)
    startTime = NSDate.timeIntervalSinceReferenceDate()

}

func countDownTime() {

    var currentTime = NSDate.timeIntervalSinceReferenceDate()

    //Find the difference between current time and start time.
    var elapsedTime: NSTimeInterval = currentTime - startTime

    //calculate the seconds in elapsed time.
    let seconds = UInt8(elapsedTime)
    elapsedTime -= NSTimeInterval(seconds)

    //find out the fraction of milliseconds to be displayed.
    let fraction = UInt8(elapsedTime * 100)

    //add the leading zero for minutes, seconds and millseconds and store them as string constants
    let strSeconds = seconds > 9 ? String(seconds):"0" + String(seconds)
    let strFraction = fraction > 9 ? String(fraction):"0" + String(fraction)

    //concatenate minuets, seconds and milliseconds as assign it to the UILabel
    timeLabel.text = "\(strSeconds):\(strFraction)"
}

在你的 countdownTime() 中,当你的流逝时间达到 20 秒时,将你的开始时间更改为当前时间

首先,如果你只是不停地循环,你可以只使用模块来获取秒数。也就是说 seconds % 20 只会从 19.9 跳到 0.0。因此,如果你倒计时,你会计算 seconds - seconds % 20 当它达到零时会跳到 20。一遍又一遍地。这就是你想要的吗?

对于前导零,您可以使用:String(format: "%02d:%02d", seconds, fraction)。请注意格式:这里的秒数和分数是整数。

但是如果您需要停止计时器,则必须跟踪之前计算的秒数并在每次开始时重置 startTime。每次停止时,您都必须将当前秒数与之前计算的秒数相加。我说的有道理吗?

您应该将日期结束时间设置为距现在 20 秒,然后只检查日期 timeIntervalSinceNow。一旦 timeInterval 达到 0,您再次将其设置为 20 秒

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var strTimer: UILabel!

    var endTime = Date(timeIntervalSinceNow: 20)
    var timer = Timer()

    @objc func updateTimer(_ timer: Timer) {
        let remaining = endTime.timeIntervalSinceNow
        strTimer.text = remaining.time
        if remaining <= 0 {
            endTime += 20
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        strTimer.font = .monospacedSystemFont(ofSize: 20, weight: .semibold)
        strTimer.text =  "20:00"
        timer = .scheduledTimer(timeInterval: 1/30, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
    }

}

extension TimeInterval {
    var time: String {
        String(format: "%02d:%02d", Int(truncatingRemainder(dividingBy: 60)), Int((self * 100).truncatingRemainder(dividingBy: 100)))
    }
}

为了尽量减少处理,您可以创建两个计时器。一个计时器为 20 秒,另一个计时器为您想要更新 UI 的频率。很难看到每秒 100 帧。如果您每 0.01 检查一次,您的代码就不太准确。手册真的很有帮助。 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/ 当您不再使用定时器时,将失效并设置为零。还存在其他计时功能。