使用 NSTimer 仅以秒为单位倒计时(从 00:20 到 0)
Countdown in seconds only (form 00:20 to 0) using NSTimer
我需要一个从 20 秒到 0 的标签倒计时,然后重新开始。这是我第一次在 Swift 做项目,我正在尝试使用 NSTimer.scheduledTimerWithTimeInterval
。此倒计时应 运行 循环给定次数。
我很难实现 Start 和 Start 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/ 当您不再使用定时器时,将失效并设置为零。还存在其他计时功能。
我需要一个从 20 秒到 0 的标签倒计时,然后重新开始。这是我第一次在 Swift 做项目,我正在尝试使用 NSTimer.scheduledTimerWithTimeInterval
。此倒计时应 运行 循环给定次数。
我很难实现 Start 和 Start 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/ 当您不再使用定时器时,将失效并设置为零。还存在其他计时功能。