Adding new delegate

ทำให้ปุ่ม Checkmark ใช้งานได้

ทีนี้เราก็เหลืออย่างเดียวละ คือทำให้ปุ่ม checkmark สามารถ toggle ค่า isDone ได้

เนื่องจาก TodoItemTableViewCell เป็น View เราจะไม่แก้ไข TodoItem เอง เราจึงสร้าง delegate ขึ้นมาใหม่เพื่อให้ Controller เราที่เป็นคนใช้ View นี้จัดการกับ Model เอง

เพิ่ม Protocol TodoItemTableViewCellDelegate กำหนดฟังก์ชั่น 1 อัน เพื่อเรียกว่าปุ่ม Checkbox โดนกดแล้วนะ

สร้างตัวแปรเก็บ delegate แก้ให้ configure(item:) รับ delegate ด้วย พร้อมกับสร้าง Action สำหรับรับ event ตอนปุ่มโดนกด โดยจะเรียกกลับไปที่ delegate

TodoItemTableViewCell.swift
import UIKit

protocol TodoItemTableViewCellDelegate: AnyObject {
    func todoItemTableViewCellDidTapCheckboxButton(cell: TodoItemTableViewCell)
}

import UIKit

class TodoItemTableViewCell: UITableViewCell {

    weak var delegate: TodoItemTableViewCellDelegate?

    @IBOutlet weak var checkboxButton: UIButton?
    @IBOutlet weak var titleLabel: UILabel?

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    func configure(item: TodoItem, delegate: TodoItemTableViewCellDelegate?) {
        titleLabel?.text = item.title
        checkboxButton?.setImage(UIImage(named: item.isDone ? "check": "uncheck"), for: .normal)
        self.delegate = delegate
    }

    @IBAction func checkboxButtonDidTap() {
        delegate?.todoItemTableViewCellDidTapCheckboxButton(cell: self)
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

จากนั้นผูกปุ่มกับ Action ที่เราสร้างโดยให้เรียกเมื่อ Touch up inside นั่นคือแตะแล้วปล่อยบนปุ่ม

จากนั้นที่ ViewController ของเราให้ประกาศตัวเป็น TodoItemTableViewCellDelegate พร้อมส่งตัวเองเป็น delegate มาตอน configure cell ใน tableView(_:cellForRowAt:)

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "todoItemCell", for: indexPath) as! TodoItemTableViewCell
    let item = todo.item(at: indexPath.row)
    cell.configure(item: item, delegate: self)
    return cell
}

จากนั้นเขียนฟังก์ชั่น delegate แบบนี้ เมื่อรับ event มาเราจะหาก่อนว่า cell ส่ง event มา เป็น cell ไหน todoItem อะไรที่เราต้องแก้ isDone แล้วสั่ง toggle พร้อมกับ reload ที่ cell นั้น

func todoItemTableViewCellDidTapCheckboxButton(cell: TodoItemTableViewCell) {
    if let indexPath = tableView?.indexPath(for: cell) {
        todo.item(at: indexPath.row).isDone.toggle()
        tableView?.reloadRows(at: [indexPath], with: .automatic)
    }
}

เป็นอันจบ ลองรันได้

Last updated