及时更新标签会一次全部显示

时间:2019-01-03 00:41:51

标签: ios swift label updating

我有一个标签,上面有许多点,每个点按顺序出现,相隔0.1秒

func setUpDots(numberOfDots: Int) {
    for dots in 1...numberOfDots {
        DispatchQueue.global(qos: .userInteractive).async {
            DispatchQueue.main.async {
                self.setLabelToDots(numberOfDots: dots)
            }
            usleep(100000)      // wait 0.1 sec between showing each dot
        }
    }
}

func setLabelToDots(numberOfDots: Int) {
    let dots = Array( repeating: ".", count: numberOfDots).joined()
    myLabel.text = dots
    myLabel.setNeedsDisplay()
}

但是所有点都一次出现在标签上

我应该怎么做才能使点之间出现指定的延迟而正确显示点?

感谢您的反馈。

1 个答案:

答案 0 :(得分:1)

基本上,您的for-loop的行为类似于...

for dots in 1...numberOfDots {
    self.setLabelToDots(numberOfDots: dots)
}

这是因为允许每个任务同时执行,并且延迟对下一个任务的运行时间没有影响。

您“可以”使用串行队列,也可以使用从属操作队列,但是更简单的解决方案可能是仅使用Timer

这将允许您在刻度之间设置“延迟”,并将计时器视为一种伪循环,例如

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var myLabel: UILabel!

    let numberOfDots = 10
    var dots = 0

    var timer: Timer?

    override func viewDidLoad() {
        super.viewDidLoad()
        myLabel.text = ""
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        guard timer == nil else {
            return
        }
        timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(tick), userInfo: nil, repeats: true)
    }

    @objc func tick() {
        dots += 1
        guard dots <= numberOfDots else {
            timer?.invalidate()
            timer = nil
            dots = 0
            return
        }
        numberOfDots(dots)
    }

    func numberOfDots(_ numberOfDots: Int) {
        // You could just use string consternation instead,
        // which would probably be quicker
        let dots = Array( repeating: ".", count: numberOfDots).joined()
        myLabel.text = dots
        myLabel.setNeedsDisplay()
    }
}

还有许多其他示例,但是您也应该看看documentation for Timer