我正在制作一个计时器程序,它使用 slider 设置计时器值,然后更新数字时钟显示以将相应的剩余数字时间显示为图像文件。
我试图在 while 循环内运行 1 秒延迟函数,并每秒更新图像文件,本质上是尝试创建一个计时器,该计时器更新用于确定实时使用哪些图像的变量。
我很难正确分配倒计时:用于设置图像文件的变量 h
, min1
和min2
设置为0
延迟 1 秒后。看起来 while 循环调用了一次延迟函数,迭代直到满足条件而不延迟计时器,然后显示最终值。
我尝试了不同的方法来计时 1 秒延迟,包括使用 let timer = Timer.
方法和DispatchQueue.main.
方法,但似乎不起作用。
@IBAction func slider(_ sender: UISlider)
{
self.x = Int(sender.value)
// Note I omitted the rest of this code as it concerned setting images while changing slider value, and used local variables.
}
var x: Int = 60
var h: Int = 1
var min1: Int = 1
var min2: Int = 7
@objc func animate2 ()
{
checkLbl.text = String(h) + ("1")
checkLbl2.text = String(min1) + ("1")
checkLbl3.text = String(min2) + ("1")
self.H2ImageView.image = UIImage(named: "\(h).png")!
self.M1ImageView.image = UIImage(named: "\(min1).png")!
self.M2ImageView.image = UIImage(named: "\(min2).png")!
}
func animate ()
{
var timeLeft = x
var seconds = 60
while timeLeft >= 0
{
(h, _) = x.quotientAndRemainder(dividingBy: 60)
(min1, min2) = x.quotientAndRemainder(dividingBy: 10)
if min1 >= 6
{
min1 = min1 - 6
if h == 2
{
min1 = 0
}
}
checkLbl.text = String(h)
checkLbl2.text = String(min1)
checkLbl3.text = String(min2)
// checkLbl used to track the variables
perform(#selector(animate2), with: nil, afterDelay: 1)
seconds = seconds - 1
if seconds == 0
{
timeLeft = timeLeft - 1
seconds = 60
}
}
}
@IBAction func watchPress(_ sender: UIButton)
{
animate()
}
总结一下:我预计延迟函数会更新h
, min1
和min2
(因此更新 checkLbl
文本)每秒但是这些值直接进入 0
.
感谢任何帮助,谢谢!
最佳答案
您需要了解,performSelector
、DispatchQueue.main.asyncAfter
和 Timer
都在一定时间后异步运行代码。这意味着在此示例中,B 行不会在 A 行之后运行一秒:
checkLbl3.text = String(min2) // A
perform(#selector(animate2), with: nil, afterDelay: 1)
seconds = seconds - 1 // B
B 行将在 A 行之后立即运行。一秒钟后,animate2
将被调用。
因此,不应使用 while 循环。相反,您应该使用像这样的Timer
:
Timer(timeInterval: 1, repeats: true) { (timer) in
if timeLeft == 0 {
timer.invalidate()
}
seconds -= 1
if seconds == 0
{
timeLeft = timeLeft - 1
seconds = 60
}
// update the labels and image views
}
我还建议您仅将剩余时间存储为秒数。删除 h
、min1
、min2
和 seconds
变量。仅从更新 UI 时剩余的时间开始计算它们。
关于swift - 使用执行(afterDelay :) within a while loop gives me a logic error?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55569227/