# Edit todo item

## หน้า Edit

หน้า edit เราจะใช้หน้าเดียวกันกับหน้า Add เลยเพราะมีอยู่แล้ว เพียงแค่เราเอาค่ามากรอกให้ก่อน แทนที่จะเป็นเปล่า ๆ&#x20;

เริ่มต้นให้เราสร้าง Segue เพื่อแสดงหน้า Add อีกอันหนึ่ง แต่ทีนี้เราจะแยกเป็นอีก Segue นึง  มี identifier เป็น **openEditItemSegue**

![](https://1168329629-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LGk7Utff0rVWsqK4eYO%2F-LH3PuO__IRopWfu23C8%2F-LH3kIQhG614E5dFwgBz%2FopenEdit.gif?alt=media\&token=b6218450-1e2c-4e0d-a723-22578feb75b8)

จากนั้นที่ AddNewItemViewController จะต้องเพิ่มตัวแปรที่ใช้เก็บ todo item ที่เราจะแก้ เพื่อเอามาใช้ในการกรอกค่าใน TextField และ Switch

```swift
var todoItem: TodoItem?
```

เมื่อหน้า Add ถูกโหลด เราก็**ตรวจว่ามี todo item ที่ใช้แก้ไหม** ถ้ามีเราก็ set ค่าใน TextField และ Switch พร้อมเปลี่ยนหัว Title เป็น **Edit item หรือ Add new item** ด้วย

```swift
override func viewDidLoad() {
    super.viewDidLoad()

    if let todoItem = todoItem {
        title = "Edit item"
        titleTextField.text = todoItem.title
        isDoneSwitch.setOn(todoItem.isDone, animated: true)
    } else {
        title = "Add new item"
    }
}
```

จากนั้นเพื่อให้หน้าแรกรู้ว่าแก้เสร็จแล้วเหมือนตอน Add เราจะเพิ่มฟังก์ชั่นใน delegate

```swift
func addNewItemViewController(controller: AddNewItemViewController, didEdit item: TodoItem)
```

พอผู้ใช้กด Done เราก็ตรวจว่าตอนนี้เป็น Edit หรือ Add ถ้าเป็น Add เราก็สร้างของแล้วเรียก delegate Add กลับไป แต่ถ้าเป็น Edit เราก็ต้อง set ค่ากลับใน todo item ตามที่กรอกเข้ามา แล้วเรียก delegate Edit กลับไป

```swift
@IBAction func doneButtonDidTap(_ sender: UIBarButtonItem) {
    if let title = titleTextField.text, !title.isEmpty {
        if let todoItem = todoItem {
            todoItem.title = title
            todoItem.isDone = isDoneSwitch.isOn
            delegate?.addNewItemViewController(controller: self, didEdit: todoItem)
        } else {
            let todoItem = TodoItem(title: title, isDone: isDoneSwitch.isOn)
            delegate?.addNewItemViewController(controller: self, didAdd: todoItem)
        }
    }
}
```

if ซ้อน if ดูไม่ค่อยสวย เราเขียนให้เป็น Swifty ได้อีกหน่อย ด้วยการใช้ guard ถ้าเราไม่สามารถอ่านค่า title ได้ หรือ title เป็นค่าว่างเราก็จะไม่ทำอะไรต่อ Return ไปเลย

```swift
@IBAction func doneButtonDidTap(_ sender: UIBarButtonItem) {
    guard let title = titleTextField.text, !title.isEmpty else {
        return
    }
    if let todoItem = todoItem {
        todoItem.title = title
        todoItem.isDone = isDoneSwitch.isOn
        delegate?.addNewItemViewController(controller: self, didEdit: todoItem)
    } else {
        let todoItem = TodoItem(title: title, isDone: isDoneSwitch.isOn)
        delegate?.addNewItemViewController(controller: self, didAdd: todoItem)
    }
}
```

กลับมาที่ ViewController เราต้องเพิ่ม delegate ฟังก์ชั่น Edit ที่เพิ่มขึ้นมา เพื่อ reload จอหน้าที่รายการนั้น

```swift
func addNewItemViewController(controller: AddNewItemViewController, didEdit item: TodoItem) {
    if let index = todo.index(of: item) {
        tableView?.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
    }
    controller.dismiss(animated: true, completion: nil)
}
```

เรายังขาดคนที่สั่งให้ Segue ทำงาน เพราะเราผูกจาก Controller ไปยังหน้า Edit ไม่ได้ผูกจากปุ่มแบบตอนกด Add เราจึงต้องสั่งเอง Manual ตอนที่เรากดที่ cell

เพิ่ม **performSegue(withIdentifier:sender:)** ที่ **tableView(\_:didSelectRowAt:)** โดยเราจะส่ง todoItem ไปตอนสั่ง Segue ด้วย

```swift
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    performSegue(withIdentifier: "openEditItemSegue", sender: todo.item(at: indexPath.row))
}
```

ทีนี้เราก็พร้อมละ แต่ครบแล้วหรือยัง ยังไม่ครบนะ เรายังไม่ได้ส่ง todo item ไปให้หน้า Edit เลย เราจะส่งผ่านไปตอนที่เรา **prepare(for:sender:)** ตามนี้

```swift
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "openAddItemSegue" {
        if let nav = segue.destination as? UINavigationController,
            let controller = nav.topViewController as? AddNewItemViewController {
            controller.delegate = self
        }
    } else if segue.identifier == "openEditItemSegue" {
        if let nav = segue.destination as? UINavigationController,
            let controller = nav.topViewController as? AddNewItemViewController {
            controller.todoItem = sender as? TodoItem
            controller.delegate = self
        }
    }
}
```

![](https://1168329629-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LGk7Utff0rVWsqK4eYO%2F-LH3PuO__IRopWfu23C8%2F-LH3pEp8JXzc-8iRO-d3%2Fedit.gif?alt=media\&token=225cd376-7af7-42eb-96bc-989f7549a352)

สุดท้ายลองปรับหน้าจอกันหน่อย ลองทำให้เป็นแบบนี้ดูสิว่าทำอย่างไร

![](https://1168329629-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LGk7Utff0rVWsqK4eYO%2F-LHNzVjqkXYsB_GPTfLr%2F-LHNzbmHrg1YuqSrETwj%2FScreen%20Shot%202018-07-14%20at%2020.31.41.png?alt=media\&token=dd30f237-6547-4456-930b-c99c15168abb)
