iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 7
1
自我挑戰組

Hey! UIKit, 做個朋友吧~系列 第 7

Day 07: 鐵人賽還沒發文啊QQ我先睡一下十分鐘之後叫我起床

這個標題某種意義上其實還滿驚悚的...

其實本來是想做倒數計時器跟紀念日倒數2個專案的。
結果紀念日做到一半發覺根本跟倒數計時器差不多啊~~
我還是把時間花在其他事情上好了

倒數計時器

現在來用date picker跟timer做個模仿apple鬧鐘的計時器功能。
可以選擇倒數時間,啟動後可暫停或取消,時間到後會跳出一個alert。

首先建立相關的UIKit及設定相關參數,畫面中總共出現了一個label、一個datePicker還有開始及取消2個button。
接下來設定3個參數:

// 限定倒數時間的格式以指定給label
let formatter = DateFormatter()

// 設定倒數計時器
var settingTimer: Timer?

// 設定倒數時間,初始值設為0
var countDownTime: TimeInterval = 0

並指定時間的格式:

formatter.dateFormat = "HH:mm:ss"

初始將datePicker跟label的center設為同一點,並將label隱藏,等開始倒數後再作切換,並使cancelButton一開始為disable。

countDownLabel.isHidden = true
cancelButton.isEnabled = false

建立一個function,用來在倒數結束或使用者按下cancel按鈕時終止時間,並將畫面及狀態切換為初始狀態:

func endTimer() {
    settingTimer?.invalidate()

    alarmDatePicker.isHidden = false
    countDownLabel.isHidden = true
    cancelButton.isEnabled = false
        
    startButton.setTitle("START", for: .normal)
    countDownTime = 0
}

接下來設定按下startButton會執行的動作吧~

@objc func startAction(_ sender: UIButton) {
    alarmDatePicker.isHidden = true
    countDownLabel.isHidden = false
    cancelButton.isEnabled = true
    
    // 判斷目前是在剛開始倒數或是暫停後重新倒數的狀態
    // 如果是剛開始倒數,countDownTime會是初始值0,把alarmDatePicker的時間指定給countDownTime
    // 如果是暫停後重新倒數的話,countDownTime沒有被歸零,會從暫停的時間點繼續倒數
    if countDownTime == 0 {
        countDownLabel.text = formatter.string(from: alarmDatePicker.date)
        countDownTime = alarmDatePicker.countDownDuration
    }
        
    if startButton.titleLabel?.text == "START" {
        startButton.setTitle("PAUSE", for: .normal)
            
        settingTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { (settingTimer) in
            if self.countDownTime != 0 {
                self.countDownTime -= 1
                
                // 將新的countDownTime轉為有小時分鐘秒數的DateComponents給countDownLabel顯示
                let hour = Int(self.countDownTime) / 3600
                let minute = (Int(self.countDownTime) % 3600) / 60
                let second = (Int(self.countDownTime) % 3600) % 60
                    
                let dateComponents = DateComponents(calendar: Calendar.current, hour: hour, minute: minute, second: second)

                self.countDownLabel.text = self.formatter.string(from: dateComponents.date!)
            } else {
                self.endTimer()
                
                // 設置倒數結束後的alert
                let alarmController = UIAlertController(title: nil, message: "Time's Up", preferredStyle: .alert)
                alarmController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                self.present(alarmController, animated: true, completion: nil)
            }
        }
    } else if startButton.titleLabel?.text == "PAUSE" {
        //終止現有timer並將按鈕回復為START
        startButton.setTitle("START", for: .normal)
        settingTimer?.invalidate()
    }
}

再設定按下cancelButton會執行的動作,就是將一切回歸原始O_O

@objc func cancelAction(_ sender: UIButton) {
    endTimer()
}

最後再分別把startAction及cancelAction加入startButton及cancelButton裡就完成啦~

(看我再貼一次)

那終於把UIDatePicker跟Timer講完啦~他們可以做很多的用途呢!
下一回要講UIPageControl。


上一篇
Day 06: 回到過去吧!前往命運石之門
下一篇
Day 08: 蛤?你說你在哪?我沒看到你啊UIPageControl
系列文
Hey! UIKit, 做個朋友吧~30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
阿展展展
iT邦好手 1 級 ‧ 2020-01-02 06:04:11

常常上演...早上:我再..再賴床一下就好
.
.
.
.
.
然後就快要午餐時間了/images/emoticon/emoticon46.gif

我要留言

立即登入留言