昨天我們完成了 AddAlarmViewController 的 UI 與資料操作邏輯,可以新增、更新或刪除鬧鐘。
今天要延續下半部分,加入 TableView 的顯示、頁面跳轉,以及通知排程,讓鬧鐘能夠正確設定提醒。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 4 }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "AddAlarmTableViewCell", for: indexPath) as! AddAlarmTableViewCell
switch indexPath.row {
case 0: // 重複
cell.lbAddAlarm.text = "重複"
cell.lbPushToRepoeat.isHidden = false
cell.lbPushToRepoeat.text = repeatTitle()
cell.accessoryType = .disclosureIndicator
case 1: // 標籤
cell.lbAddAlarm.text = "標籤"
cell.txfRename.isHidden = false
cell.txfRename.text = alarmname
cell.txfRename.delegate = self
case 2: // 提示聲
cell.lbAddAlarm.text = "提示聲"
cell.lbPushToSound.isHidden = false
cell.lbPushToSound.text = selectedSound.isEmpty ? "預設提示聲" : selectedSound
cell.accessoryType = .disclosureIndicator
case 3: // 稍後提醒
cell.lbAddAlarm.text = "稍後提醒~"
cell.swAddAlarm.isHidden = false
cell.swAddAlarm.isOn = snoozeEnabled
cell.swAddAlarm.addTarget(self, action: #selector(snoozeSwitchChanged(_:)), for: .valueChanged)
default: break
}
return cell
}
這裡的 TableView 一共有四列:重複、標籤、提示聲、稍後提醒,分別對應不同的設定項目。
@objc func repeatButtonTapped() {
let repeatVC = RepeatViewController()
repeatVC.selectedDays = repeatDays
repeatVC.delegate = self
navigationController?.pushViewController(repeatVC, animated: true)
}
@objc func soundButtonTapped() {
let soundVC = SoundViewController()
soundVC.delegate = self
soundVC.currentSelectedSound = selectedSound
navigationController?.pushViewController(soundVC, animated: true)
}
點擊「重複」會跳轉到 RepeatViewController,點擊「提示聲」則會跳轉到 SoundViewController。
func scheduleNotification(for alarm: AlarmData) {
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = alarm.name
content.body = "\(alarm.alarmTime) TimeOut!!!"
content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "\(alarm.sound).mp3"))
let dateComponents = Calendar.current.dateComponents([.hour, .minute], from: formatStringToDate(alarm.alarmTime) ?? Date())
if alarm.repeatDays.contains(true) {
for (index, isSelected) in alarm.repeatDays.enumerated() where isSelected {
var triggerDateComponents = dateComponents
triggerDateComponents.weekday = index + 1
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDateComponents, repeats: true)
let request = UNNotificationRequest(identifier: "\(alarm.creatTime)_\(index)", content: content, trigger: trigger)
center.add(request)
}
} else {
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
let request = UNNotificationRequest(identifier: alarm.creatTime, content: content, trigger: trigger)
center.add(request)
}
}
這段程式能排程單次鬧鐘與重複鬧鐘,確保時間到時會觸發本地通知。
extension AddAlarmViewController: RepeatViewControllerDelegate {
func didUpdateRepeatDays(_ days: [Bool]) {
repeatDays = days
tbvAddAlarm.reloadData()
}
}
extension AddAlarmViewController: SoundViewControllerDelegate {
func didSelectSound(_ sound: String) {
selectedSound = sound
tbvAddAlarm.reloadData()
}
}
RepeatViewController 與 SoundViewController 的資料會透過 Delegate 回傳,讓 AddAlarmViewController 即時更新畫面。
今天我們完成了 AddAlarmViewController 的下半部分,包含 TableView 顯示、頁面跳轉以及通知排程。
到這裡為止,新增與編輯鬧鐘的功能已經完整具備。
接下來的教學會開始介紹 RepeatViewController 的設計,讓重複天數的選擇能夠正確運作。