我正在设置一个应用程序以充当简单的计时器,它只是一个单视图应用程序,具有针对每个不同长度的一些功能。
按下按钮时,变量会更新,因为我将其设置为可打印,只是标签未更新。
我尝试了几种尝试将其放在主线程上的方法,但是没有用。
import UIKit
import AudioToolbox
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
var seconds = 0
var stateOfPotentialBurning = false
var shouldBeRunning = true
@IBOutlet weak var timeLeft: UILabel!
@IBOutlet weak var currentState: UILabel!
@IBAction func basicFish(_ sender: Any) {
basicFishTimer()
}
@IBAction func basicMeat(_ sender: Any) {
basicMeatTimer()
}
@IBAction func trophyFish(_ sender: Any) {
trophyFishTimer()
}
@IBAction func monsterMeat(_ sender: Any) {
monsterMeatTimer()
}
@IBAction func offStop(_ sender: Any) {
shouldBeRunning = false
seconds = 0
timeLeft.textColor = UIColor.black
currentState.textColor = UIColor.black
stateOfPotentialBurning = false
}
func basicFishTimer() {
print(1)
DispatchQueue.main.async() {
self.currentState.text = "Cooking"
}
seconds = 45
DispatchQueue.main.async() {
self.timeLeft.text = String(self.seconds)
}
print(2)
while (seconds > 0 && shouldBeRunning == true) {
seconds -= 1
DispatchQueue.main.async() {
self.timeLeft.text = String(self.seconds)
}
sleep(1)
print(seconds)
}
stateOfPotentialBurning = true
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
seconds = 0
print(3)
while stateOfPotentialBurning == true && shouldBeRunning == true{
DispatchQueue.main.async() {
self.currentState.text = "Done"
}
DispatchQueue.main.async() {
self.timeLeft.textColor = UIColor.red
}
seconds -= 1
if (seconds == 0) {
seconds = 0
DispatchQueue.main.async() {
self.currentState.text = "Burnt"
}
self.currentState.text = "Burnt"
DispatchQueue.main.async() {
self.currentState.textColor = UIColor.red
}
currentState.textColor = UIColor.red
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
stateOfPotentialBurning = false
shouldBeRunning = false
}
sleep(1)
print(4)
}
}
func basicMeatTimer() {
currentState.text = "Cooking"
seconds = 65
repeat {
seconds -= 1
timeLeft.text = "\(seconds)"
sleep(1)
} while seconds > 0 && shouldBeRunning == true
stateOfPotentialBurning = true
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
seconds = 0
while stateOfPotentialBurning == true && shouldBeRunning == true{
currentState.text = "Done"
timeLeft.textColor = UIColor.red
seconds -= 1
if (seconds == 0) {
seconds = 0
currentState.text = "Burnt"
currentState.textColor = UIColor.red
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
stateOfPotentialBurning = false
shouldBeRunning = false
}
sleep(1)
}
}
func trophyFishTimer() {
currentState.text = "Cooking"
seconds = 95
repeat {
seconds -= 1
timeLeft.text = "\(seconds)"
sleep(1)
} while seconds > 0 && shouldBeRunning == true
stateOfPotentialBurning = true
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
seconds = 0
while stateOfPotentialBurning == true && shouldBeRunning == true{
currentState.text = "Done"
timeLeft.textColor = UIColor.red
seconds -= 1
if (seconds == 0) {
seconds = 0
currentState.text = "Burnt"
currentState.textColor = UIColor.red
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
stateOfPotentialBurning = false
shouldBeRunning = false
}
sleep(1)
}
}
有效,只是标签不更新
答案 0 :(得分:3)
在iOS上不要使用无限while循环(或while running
)循环。那会阻塞运行循环的线程。在循环返回之前,您尝试通过调用DispatchQueue.main.async()
来更新UI的尝试将不会起作用。
根据Issac的建议,使用Timer
对象。这样可以在正确的时间调用您的代码,并且可以在前台或后台线程上工作。
答案 1 :(得分:-1)
使用Timer.scheduledTimer()函数获取更多信息,以快速的文章https://www.hackingwithswift.com/articles/117/the-ultimate-guide-to-timer阅读此技巧