Swift:在循环内更新标签

时间:2018-11-04 12:50:36

标签: ios swift

我有一个可以运行一段时间的功能。在运行时,我想在屏幕上提供反馈。

问题在于label.text没有更新。

我怀疑这是因为我需要在后台执行该功能,否则在viewDidAppear方法中执行“暂停”。但是,如果这样做,我认为在后台进行更新也不会更新文本。因此,我认为我必须再次在主线程上更新label.text。

但是当我这样做时,我遇到了运行时错误:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        DispatchQueue.main.async {
            for i in 1...10 {
                DispatchQueue.main.sync {
                    self.label.text = "Working on item \(i)..."
                }
                sleep(1)
            }
        }
    }
}

我看过this post,但是这些方法似乎过时了,在Xcode 10 / Swift 4中不起作用。

2 个答案:

答案 0 :(得分:1)

问题是您在主线程中运行了for循环。这意味着一个渲染框架将执行整个for循环。

您应该仅在后台线程上运行长任务,并在主线程中更新必要的UI元素:

  DispatchQueue.global(qos: .background).async {// global() will use a background thread rather than the main thread
            for i in 1...10 {
                DispatchQueue.main.sync {
                    self.label.text = "Working on item \(i)..."
                }
                sleep(1)
            }
        }

答案 1 :(得分:0)

我对后台队列进行了一些研究,发现this post

在我的示例中使用它-可以做到:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        DispatchQueue.global(qos: .background).async {
            for i in 1...10 {
                DispatchQueue.main.async {
                    self.label.text = "Working on item \(i)..."
                }
                sleep(1)
            }
        }
    }
}