我知道我可以使用followign语法(How to program a delay in Swift 3)延迟Swift 3中的部分代码:
let when = DispatchTime.now() + 2 // change 2 to desired second delay.
DispatchQueue.main.after(when: when) {
// run your code with delay
}
或类似的帖子:How to create dispatch queue in Swift 3
然而,这些不是我可以使用的延迟方法。我需要在循环中插入一个延迟。例如,假设有一个标签组件和一个按钮。当我单击按钮时,我希望标签连续显示循环变量:
@IBOutlet weak var showIntegers: UILabel!
@IBAction func countNums(_ sender: AnyObject) {
for i in 1...5 {
showIntegers.text = String(i)
//delay code here, sleep(1) doesn't work
}
}
我使用睡眠作为延迟,然后应用程序睡眠5秒然后显示5.我连续看不到1,2,3,4和5,延迟时间为1秒。
我也无法弄清楚如何在循环中使用DispatchQueue类。感谢您的帮助。
答案 0 :(得分:7)
sleep
无法正常工作,因为GUI需要一些时间才能更新,但是在更新标签后,您会立即在主队列中休眠。您的应用程序在此期间将无响应,标签将从0跳到5,偶尔会有一些变化。
使用Grand Central Dispatch async_after
代替(在Swift 2中曾是dispatch_after
):
@IBAction func countNums(_ sender: AnyObject) {
for i in 1...5 {
// Always update your GUI on the main thread
DispatchQueue.main.asyncAfter(deadline: .now() + Double(i)) {
self.showIntegers.text = "\(i)"
}
}
}
答案 1 :(得分:2)
您似乎正在寻找类似于我使用的东西。
请注意,我没有使用DispatchQueue,但更简单的计时器:
@IBAction func countNums(_ sender: AnyObject) {
for i in 1...5 {
Timer.scheduledTimer(timeInterval: Double(i - 1), // first timer triggers immediately, the others with 1 second delay from the previous timer
target: self,
selector: #selector(...myFunc(_:)), // please define here your func to call after the timer has triggered (see example below)
userInfo: i, // pass here the value that will be read inside the method myFunc
repeats: false))
}
}
// method called when the timer triggers
func myFunc(_ timer: Timer) {
guard let index = timer.userInfo as? Int else { return }
showIntegers(index)
}
// finally, actual action
fun showIntegers(_ i: Int) {
showIntegers.text = String(i)
}
另请注意,您可以合并两个函数showIntegers
和myFunc
:我已将它们分开,因为在我看来,代码看起来更加清晰。