及时更新标签一次显示
Updating label in time shows up all at once
我有一个标签,我想用一些点填充,每个点按顺序出现,间隔 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()
}
但所有的点都同时出现在标签上
我应该怎么做才能使点之间的指定延迟出现正确的效果?
感谢您的反馈。
基本上,您的 for-loop
正在做类似于...
for dots in 1...numberOfDots {
self.setLabelToDots(numberOfDots: dots)
}
这是因为允许每个任务同时执行,而延迟对下一个任务何时执行没有影响运行。
您 "could" 使用串行队列或者您可以使用依赖操作队列,但更简单的解决方案可能是只使用 Timer
这将允许您在滴答之间设置 "delay" 并将计时器视为一种伪循环,例如
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
我有一个标签,我想用一些点填充,每个点按顺序出现,间隔 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()
}
但所有的点都同时出现在标签上
我应该怎么做才能使点之间的指定延迟出现正确的效果?
感谢您的反馈。
基本上,您的 for-loop
正在做类似于...
for dots in 1...numberOfDots {
self.setLabelToDots(numberOfDots: dots)
}
这是因为允许每个任务同时执行,而延迟对下一个任务何时执行没有影响运行。
您 "could" 使用串行队列或者您可以使用依赖操作队列,但更简单的解决方案可能是只使用 Timer
这将允许您在滴答之间设置 "delay" 并将计时器视为一种伪循环,例如
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