Pushing edit view

Push จากทางขวาสิ

รู้สึกแปลก ๆ ไหมเวลาเรากดดู Detail หรือจะ edit แล้วมันเปิดขึ้นมาเต็มจอแบบหน้า Add ทั้ง ที่มีเครื่องหมายชี้ออกไปด้ายขวา (>)

เราจะมาแก้ให้มันเลื่อนเข้ามาจากทางขวาแทน แบบในแอป Setting

  1. เราต้องแก้ Segue ของเราก่อนโดยลบ openEditItemSegue เดิมออกก่อน

  2. ลาก Segue ใหม่จาก TodoListViewController ไปยัง ItemDetailViewController โดยการกด Ctrl ค้างแล้วลากจากปุ่มเหลือง ๆ บน TodoListViewController ไปหน้า ItemDetailViewController เลือก Manual Segue เป็น Show

  3. ตั้ง identifier ให้ segue เป็นชื่อเดิม openEditItemSegue

จากนั้นแก้โค้ดส่วน prepare(for:sender:) ส่วน openEditItemSegue ให้ cast destination เป็น ItemDetailViewController แทน UINavigationController

เพราะ destination ของ segue ไม่ได้ชี้ที่ UINavigationController แล้ว

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

จากนั้นเมื่อรันแล้วจะพบว่า หน้า edit จะ push เข้ามาจากทางขวามือแล้ว แต่เมื่อเรากด Cancel หรือ Done จะไม่สามารถใช้งานได้ นั่นเพราะเมื่อเราไม่ได้เปิดแบบ Modal แล้วเราจะไม่สามารถ dismiss viewController ได้

Navigation Controller จะทำงานในลักษณะ Stack เมื่อเราเปิดหน้าใหม่ NavigationController จะ Push หน้าใหม่เข้ามา ดังนั้นเพื่อให้ปิดหน้า edit เราจึงจะต้อง Pop ออกจาก NavigationController

ให้เราเปลี่ยนเป็น popViewController จากเดิมที่สั่ง dismiss controller ในส่วนของ itemDetailViewController(controller:didEdit:)

TodoListViewController.swift
func itemDetailViewController(controller: ItemDetailViewController, didEdit item: TodoItem) {
    if let index = todo.index(of: item) {
        tableView?.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
    }
    navigationController?.popViewController(animated: true)
}

และใน itemDetailViewControllerDidCancel(controller:) เมื่อเป็นการ cancel จาก edit

TodoListViewController.swift
func itemDetailViewControllerDidCancel(controller: ItemDetailViewController) {
    if controller.isInEditMode {
        navigationController?.popViewController(animated: true)
    } else {
        controller.dismiss(animated: true, completion: nil)
    }
}

IsInEditMode ใน ItemDetailViewController.swift คือตรวจว่ามี todoItem หรือไม่

ItemDetailViewController.swift
var isInEditMode: Bool {
    todoItem != nil
}

เสร็จเรียบร้อย Push Pop ถูกต้อง

Last updated