其實跟回到過去一點關係也沒有
為了完成下一篇要實作的小專案,現在來離題一波講講timer。
timer是一個計時器,當timer啟動後,每隔一段時間區間(time interval),timer就會傳送一個selector function給target執行。
在初始化timer實體的時候,可以指定repeats的boolean為true或false。
如果repeats為false,則timer只會被觸發一次,觸發後即之後自動失效。
而repeats若為true,timer就會在預計觸發的同時自動生成一個一模一樣的新timer。
為什麼是說「預計觸發」呢?其實實際觸發的時間會有一個delay(tolerance),並不會完全符合預計觸發的時間。
也就是說,假如你設定了一個timeInterval為5秒會repeat的timer,他就會乖乖每5秒生成一個新timer,根本不管你抵不抵累,跟不管人聲自顧自演奏的伴奏團一樣令人火大?。
不過如果你實在delay的太嚴重,舊的timer還沒觸發掉的話,5秒後就先不會幫你生成一個新timer,也不會再對沒生成的timer進行補償。所以說起來樂隊老師還是會等的嘛~只不過到這種地步你的歌唱比賽也差不多結束了QQ
在iOS 7和macOS 10.9之後的版本,你可以自己設定timer的tolerance,timer的實際觸發時間會落在你預計觸發的時間至tolerance的區間內。而repeat的時間同樣會以預計觸發的時間為基準。
在default的情況下,tolerance為0。不過就如同剛剛所說的,實際觸發時間並不會完全符合預計觸發時間,系統還是會幫你安排一個小小的tolerance,都不管別人要不要。
如果你跟我一樣有反社會人格不想被硬塞tolerance的話,不如就自己設定吧~一般而言至少要設定10%timeInterval的時間。
不過就算是只有一點點的tolerance也是對系統效能還有省電有幫助的!雖然我不知道為什麼,是API這樣說,反正我是信了。
以下有3種初始化timer實體的方法:
當repeating timer被指派進執行迴圈後,就會像黃金鼠被放到轉輪上一樣跑個不停,直到失效為止,有夠殘忍!
所以要記得下invalidate()這個方法,以免黃金鼠都已經跑到crush了還跟著轉輪轉不停QQ一人一個細心的小動作,救救黃金鼠!!
只要invalidate()一下,timer就會立即停止,而且不能再次被指派。
接下來來實作一個簡單的倒數timer吧~
首先設定初始時間的變數,再建立一個label和一個button,並設定屬性參數及位置,這邊就不帶著大家實作了。
接下來建立一個selector function:
@objc func startCountDown(_ sender: UIButton) {
initialTime = 10
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { (timer) in
self.timeLabel.text = "倒數 \(self.initialTime) 秒"
self.startButton.isEnabled = false
if self.initialTime != 0 {
self.initialTime -= 1
} else {
timer.invalidate()
self.startButton.isEnabled = true
}
}
}
並把這個function加入button。
這個function在點擊button時會先將初始時間回復為10秒,並讓button的狀態變成disable,以避免在倒數時重複點擊到start按鈕而造成同一個執行迴圈中有2個一樣的timer同時存在。
接下來設定一個timer,每1秒會送出一個selector function給target,並且為repeating timer。
這個寫法其實跟scheduledTimer(timeInterval:target:selector:userInfo:repeats:)是一樣的,只是將selector function直接寫在閉包裡,target為timer本身。
而這個timer每1秒會將initial time減1,並回傳給time label,直到initial time=0為止,將start button恢復到可點擊狀態,並且使timer失效。
為了顯示startButton為不可點擊狀態,設定在不同狀態下start button的title顏色不同:
startButton.setTitleColor(.blue, for: .normal)
startButton.setTitleColor(.gray, for: .disabled)
我們簡單的倒數計時器就完成啦!
下一回我們會同時使用UIDatePicker和Timer實作倒數計時器,走過路過不要錯過喔~