用毫秒创建一个倒计时计时器(NSTimer),但它没有正确倒计时
Creating a countdown-timer(NSTimer) with milliseconds but it doesn't count down correctly
我是 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
}
}
}
编辑:新代码仍然没有弄清楚,但我认为这是正确的方式,我怎么能 substract/compare 两个字符串,就像我在 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)
}
}
您忽略了安排和执行对 countDownfunction
的调用实际花费的时间。 NSTimer
不会在恰好 100 毫秒后给您回电,因为 phone 正在做其他事情。它根本不会那么准确。此外,countDownfunction
调用本身会花费时间,而您没有考虑到这一点。
您应该通过记录开始时间并检查 countDownfunction
中的当前时间来解决此问题,然后将两者相减以设置您的标签。这样您就可以补偿处理计时器的任何延迟。
您可以使用NSDate.timeIntervalSinceReferenceDate()
获取当前时间。
您是否注意到您将毫秒设置为 100,而不是 1000?
因此您的计时器在 23 秒内被调用了大约 1300 次。听起来不错。是什么让您认为每秒倒数 1000 次是个好主意?人们看不到这一点。
如果你阅读 NSTimer 的文档,重复定时器会尝试在预期的时间触发(因此它们不会在上次触发后 X 秒触发,但会在上次触发后 X、2X、3X、4X 秒尝试触发)计时器已启动),但如果在给定时间内根本未触发计时器,则该触发器将被丢弃。因此,在 23 秒内,您的计时器不会触发 23,000 次,而是像人们预期的那样触发 1300 次。您不能每秒更新屏幕 1,000 次。如果可以,没有人能看到它。
运行你的计时器以合理的速度,每秒不超过30次,并计算时间是多少。不是基于倒计时,而是基于实际时间。
我是 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
}
}
}
编辑:新代码仍然没有弄清楚,但我认为这是正确的方式,我怎么能 substract/compare 两个字符串,就像我在 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)
}
}
您忽略了安排和执行对 countDownfunction
的调用实际花费的时间。 NSTimer
不会在恰好 100 毫秒后给您回电,因为 phone 正在做其他事情。它根本不会那么准确。此外,countDownfunction
调用本身会花费时间,而您没有考虑到这一点。
您应该通过记录开始时间并检查 countDownfunction
中的当前时间来解决此问题,然后将两者相减以设置您的标签。这样您就可以补偿处理计时器的任何延迟。
您可以使用NSDate.timeIntervalSinceReferenceDate()
获取当前时间。
您是否注意到您将毫秒设置为 100,而不是 1000?
因此您的计时器在 23 秒内被调用了大约 1300 次。听起来不错。是什么让您认为每秒倒数 1000 次是个好主意?人们看不到这一点。
如果你阅读 NSTimer 的文档,重复定时器会尝试在预期的时间触发(因此它们不会在上次触发后 X 秒触发,但会在上次触发后 X、2X、3X、4X 秒尝试触发)计时器已启动),但如果在给定时间内根本未触发计时器,则该触发器将被丢弃。因此,在 23 秒内,您的计时器不会触发 23,000 次,而是像人们预期的那样触发 1300 次。您不能每秒更新屏幕 1,000 次。如果可以,没有人能看到它。
运行你的计时器以合理的速度,每秒不超过30次,并计算时间是多少。不是基于倒计时,而是基于实际时间。