UILabel不在循环中更新吗?

时间:2019-05-09 17:47:48

标签: swift

我正在设置一个应用程序以充当简单的计时器,它只是一个单视图应用程序,具有针对每个不同长度的一些功能。

按下按钮时,变量会更新,因为我将其设置为可打印,只是标签未更新。

我尝试了几种尝试将其放在主线程上的方法,但是没有用。

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)

        }



    }

有效,只是标签不更新

2 个答案:

答案 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阅读此技巧