在循环中创建swift 3的延迟

时间:2016-08-29 13:22:14

标签: swift swift3

我知道我可以使用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类。感谢您的帮助。

2 个答案:

答案 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)
}

另请注意,您可以合并两个函数showIntegersmyFunc:我已将它们分开,因为在我看来,代码看起来更加清晰。