這段程式碼展示了如何使用 UITableView
來顯示資料,並包括了刪除功能、進入編輯模式等功能。以下是排版過後的程式碼,並附上註解解釋每個部分的功能。
extension MainViewController: UITableViewDelegate, UITableViewDataSource {
// 設定tableView有幾個section
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
// 設定每個section裡有多少row
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
// 根據新增的鬧鐘數量決定有多少row
return alarms.count
}
// 設定tableView每個cell要顯示的內容
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: SecondTableViewCell.identifier,
for: indexPath) as! SecondTableViewCell
// 取得每一個row對應的鬧鐘資料
let alarm = alarms[indexPath.row]
// 在cell裡顯示鬧鐘的時間和名稱
cell.lbList.text = alarm.alarmTime
cell.lbName.text = alarm.name.isEmpty ? "鬧鐘" : alarm.name
// 設定鬧鐘的開關
cell.swAlarm.isOn = alarm.isEnabled
cell.swAlarm.tag = indexPath.row // 儲存開關對應的row
cell.swAlarm.addTarget(self,
action: #selector(alarmSwitchChange(_:)),
for: .valueChanged)
// 如果在編輯模式中,隱藏開關
cell.swAlarm.isHidden = isEditing
// 加入可以點選進行編輯的樣式
cell.accessoryType = .disclosureIndicator
return cell
}
// 處理點選某一個row的動作
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// 允許該section的row被選擇
tableView.allowsSelection = true
tableView.deselectRow(at: indexPath, animated: true)
// 取得選擇的鬧鐘
let alarm = alarms[indexPath.row]
let editAlarmVC = AddAlarmViewController(nibName: "AddAlarmViewController", bundle: nil)
// 將選中的鬧鐘資料傳遞到編輯頁面
editAlarmVC.alarmToEdit = alarm
editAlarmVC.selectedSound = alarm.sound
editAlarmVC.delegate = self
// 顯示編輯頁面
let navController = UINavigationController(rootViewController: editAlarmVC)
self.present(navController, animated: true, completion: nil)
}
// 處理進入編輯模式後刪除row的動作
func tableView(_ tableView: UITableView,
commit editingStyle: UITableViewCell.EditingStyle,
forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// 根據是否開啟過濾鬧鐘
let filteredAlarms = alarms.filter {
indexPath.section == 0 ? $0.isEnabled : !$0.isEnabled
}
let alarm = filteredAlarms[indexPath.row]
deleteAlarm(alarm, at: indexPath)
}
}
// 左滑刪除的功能
func tableView(_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) ->
UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "刪除") {
[weak self] (_, _, completionHandler) in
guard let self = self else { return }
// 過濾鬧鐘
let filteredAlarms = self.alarms.filter {
indexPath.section == 0 ? $0.isEnabled : !$0.isEnabled
}
let alarm = filteredAlarms[indexPath.row]
self.deleteAlarm(alarm, at: indexPath)
completionHandler(true)
}
// 設定刪除按鈕背景顏色
deleteAction.backgroundColor = .red
return UISwipeActionsConfiguration(actions: [deleteAction])
}
}
func deleteAlarm(_ alarm: AlarmData, at indexPath: IndexPath) {
let realm = try! Realm()
// 刪除鬧鐘相關的通知
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [alarm.creatTime])
for index in 0..<7 {
UNUserNotificationCenter.current().removePendingNotificationRequests(
withIdentifiers: ["\(alarm.creatTime)_\(index)"]
)
}
// 刪除Realm資料庫中的鬧鐘
try! realm.write {
realm.delete(alarm)
}
// 移除alarms中的鬧鐘並更新tableView
alarms.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
UITableView
的 numberOfSections
和 numberOfRowsInSection
來控制有多少個 section 和 row。每個 row 的內容在 cellForRowAt
中設定。didSelectRowAt
方法來監聽使用者選擇的行,並打開編輯頁面。commit editingStyle
中處理刪除動作,並搭配 Realm 刪除鬧鐘資料。trailingSwipeActionsConfigurationForRowAt
方法來啟用左滑刪除。接下來的文章將教如何新增鬧鐘和設置通知功能。