2016-08-29 220 views
0

我知道我可以使用followign語法(How to program a delay in Swift 3)的斯威夫特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類。感謝您的幫助提前。

+1

我會給你一個非常重要的建議 - 不要插入循環中的延遲。無論何時你認爲你需要「睡眠(...)」,你都應該真正思考如何在不阻止等待的情況下寫入函數。 – Sulthan

+3

我不明白你想暫停循環的原因。但是一般來說,你不應該阻塞主線程(IBAction會在主線程中被觸發)。總是有一個更好的解決方案。您需要學會處理異步事件並在正確的時間對其進行響應。 –

+0

@M_G謝謝你的建議,但我沒有要求建議,如果你知道如何在這裏插入延遲,我會很高興,如果你分享... – Graeme

回答

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:我已經把他們分開,因爲,在我的意見,代碼看起來更清晰這種方式。

6

sleep將無法​​正常工作,因爲GUI需要一些時間才能更新,但是您在更新標籤後立即立即睡眠主隊列。您的應用程序在這段時間內沒有響應,標籤會從0跳到5,偶爾會有一些變化。

使用大中央調度async_after代替(曾經是斯威夫特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)" 
     } 
    } 
}