我有一个标签,上面有许多点,每个点按顺序出现,相隔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()
}
但是所有点都一次出现在标签上
我应该怎么做才能使点之间出现指定的延迟而正确显示点?
感谢您的反馈。
答案 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