自訂 delegate 範例 — Develop in Swift Data Collections 重點整理
利用 delegate 傳資料的相關說明可參考以下連結
接下來讓我們從 Apple 的 Develop in Swift Data Collections 挖寶,看看幾個實際的範例。
可從解答本下載範例研究。
- 範例 1: 將 view controller 的 delegate 設為前一頁的 view controller,Lesson 1.9 的 Complex Input Screens
- 範例 2: 將 view controller 的 delegate 設為前一頁的 view controller,Lesson 1.9 Lab 的 Employee Roster
- 範例 3: 將 cell 的 delegate 設為 table view controller,Unit 1 Guided project: List
範例 1: 將 view controller 的 delegate 設為前一頁的 view controller,Lesson 1.9 的 Complex Input Screens
設定 SelectRoomTypeTableViewController 的 delegate 為前一頁的 AddRegistrationTableViewController,讓 SelectRoomTypeTableViewController 能將選擇的房間類型傳給前一頁的 AddRegistrationTableViewController。
HotelManzana
SelectRoomTypeTableViewController.swift
- 定義 protocol SelectRoomTypeTableViewControllerDelegate
protocol SelectRoomTypeTableViewControllerDelegate: AnyObject {
func selectRoomTypeTableViewController(_ controller: SelectRoomTypeTableViewController, didSelect roomType: RoomType)
}
- 宣告 property delegate
class SelectRoomTypeTableViewController: UITableViewController {
weak var delegate: SelectRoomTypeTableViewControllerDelegate?
- 點選表格時呼叫 delegate 的 function
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
roomType = RoomType.all[indexPath.row]
delegate?.selectRoomTypeTableViewController(self, didSelect: roomType)
tableView.reloadData()
}
AddRegistrationTableViewController.swift
- 遵從 protocol SelectRoomTypeTableViewControllerDelegate
class AddRegistrationTableViewController: UITableViewController, SelectRoomTypeTableViewControllerDelegate
- 在 IBSegueAction 生成 SelectRoomTypeTableViewController 時設定 delegate
@IBSegueAction func selectRoomType(_ coder: NSCoder) -> SelectRoomTypeTableViewController? {
let selectRoomTypeController = SelectRoomTypeTableViewController(coder: coder)
selectRoomTypeController?.delegate = self
selectRoomTypeController?.roomType = roomType
return selectRoomTypeController
}
- 定義 protocol SelectRoomTypeTableViewControllerDelegate 的 function selectRoomTypeTableViewController(_:didSelect:)
func selectRoomTypeTableViewController(_ controller: SelectRoomTypeTableViewController, didSelect roomType: RoomType) {
self.roomType = roomType
updateRoomType()
updateChargesSection()
}
範例 2: 將 view controller 的 delegate 設為前一頁的 view controller,Lesson 1.9 Lab 的 Employee Roster
概念和範例 1 類似,有興趣的朋友可進一步研究。
範例 3: 將 cell 的 delegate 設為 table view controller,Unit 1 Guided project: List
設定 ToDoCell 的 delegate 為 ToDoTableViewController,讓 ToDoCell 在點選 checkmark 時通知 ToDoTableViewController。
ToDoList
點選 checkmark 時,ToDoCell 利用 delegate 通知 ToDoTableViewController。
ToDoCell.swift
- 定義 protocol ToDoCellDelegate
protocol ToDoCellDelegate: AnyObject {
func checkmarkTapped(sender: ToDoCell)
}
- 宣告 property delegate
class ToDoCell: UITableViewCell {
weak var delegate: ToDoCellDelegate?
- 點選 checkmark 時呼叫 delegate 的 function
@IBAction func completeButtonTapped(_ sender: UIButton) {
delegate?.checkmarkTapped(sender: self)
}
ToDoTableViewController.swift
- 遵從 protocol ToDoCellDelegate
class ToDoTableViewController: UITableViewController, ToDoCellDelegate
- 產生 cell 時,將 controller 設為 cell 的 delegate
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ToDoCellIdentifier", for: indexPath) as! ToDoCell
let todo = todos[indexPath.row]
cell.titleLabel?.text = todo.title
cell.isCompleteButton.isSelected = todo.isComplete
cell.delegate = self
return cell
}
- 定義 protocol ToDoCellDelegate 的 function checkmarkTapped。
從 cell 找出它的 indexPath,然後修改 array 裡的資料,更新表格和儲存資料。
func checkmarkTapped(sender: ToDoCell) {
if let indexPath = tableView.indexPath(for: sender) {
var todo = todos[indexPath.row]
todo.isComplete.toggle()
todos[indexPath.row] = todo
tableView.reloadRows(at: [indexPath], with: .automatic)
ToDo.saveToDos(todos)
}
}