Обновление метки во времени появляется все сразу - PullRequest
0 голосов
/ 03 января 2019

У меня есть метка, которую я хотел бы заполнить количеством точек, каждая точка должна появляться в последовательности, разделенных на 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 голосов
/ 03 января 2019

По сути, ваш 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()
    }
}

Существует множество других примеров, но вы также должны взглянуть на документацию для Timer

...