From a937823c434f79edece89da8b9c136b91ce93163 Mon Sep 17 00:00:00 2001 From: John Hampton Date: Wed, 6 Mar 2019 18:01:45 -0500 Subject: [PATCH] Implements Edit and Delete behavior --- iOSTemplate/Base.lproj/Main.storyboard | 6 ++- iOSTemplate/MealTableViewController.swift | 58 +++++++++++++++++------ iOSTemplate/MealViewController.swift | 21 +++++++- 3 files changed, 69 insertions(+), 16 deletions(-) diff --git a/iOSTemplate/Base.lproj/Main.storyboard b/iOSTemplate/Base.lproj/Main.storyboard index fa82120..66a876d 100644 --- a/iOSTemplate/Base.lproj/Main.storyboard +++ b/iOSTemplate/Base.lproj/Main.storyboard @@ -47,6 +47,7 @@ + @@ -174,10 +175,13 @@ - + + + + diff --git a/iOSTemplate/MealTableViewController.swift b/iOSTemplate/MealTableViewController.swift index 0e33df8..7425965 100644 --- a/iOSTemplate/MealTableViewController.swift +++ b/iOSTemplate/MealTableViewController.swift @@ -6,6 +6,7 @@ // import UIKit +import os.log class MealTableViewController: UITableViewController { // MARK: Properties @@ -14,6 +15,9 @@ class MealTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() + + // Use the edit button item provided by the table view controller. + navigationItem.leftBarButtonItem = editButtonItem // Load the sample data. loadSampleMeals() @@ -46,25 +50,22 @@ class MealTableViewController: UITableViewController { return cell } - /* // Override to support conditional editing of the table view. override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the specified item to be editable. return true } - */ - /* // Override to support editing the table view. - override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { + override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { // Delete the row from the data source + meals.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .fade) } else if editingStyle == .insert { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } } - */ /* // Override to support rearranging the table view. @@ -81,25 +82,54 @@ class MealTableViewController: UITableViewController { } */ - /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. + super.prepare(for: segue, sender: sender) + + switch(segue.identifier ?? "") { + + case "AddItem": + os_log("Adding a new meal.", log: OSLog.default, type: .debug) + + case "ShowDetail": + guard let mealDetailViewController = segue.destination as? MealViewController else { + fatalError("Unexpected destination: \(segue.destination)") + } + + guard let selectedMealCell = sender as? MealTableViewCell else { + fatalError("Unexpected sender: \(String(describing: sender))") + } + + guard let indexPath = tableView.indexPath(for: selectedMealCell) else { + fatalError("The selected cell is not being displayed by the table") + } + + let selectedMeal = meals[indexPath.row] + mealDetailViewController.meal = selectedMeal + + default: + fatalError("Unexpected Segue Identifier; \(String(describing: segue.identifier))") + } } - */ // MARK: Actions @IBAction func unwindToMealList(sender: UIStoryboardSegue) { if let sourceViewController = sender.source as? MealViewController, let meal = sourceViewController.meal { - // Add a new meal. - let newIndexPath = IndexPath(row: meals.count, section: 0) - - meals.append(meal) - tableView.insertRows(at: [newIndexPath], with: .automatic) + if let selectedIndexPath = tableView.indexPathForSelectedRow { + // Update an existing meal. + meals[selectedIndexPath.row] = meal + tableView.reloadRows(at: [selectedIndexPath], with: .none) + } + else { + // Add a new meal. + let newIndexPath = IndexPath(row: meals.count, section: 0) + + meals.append(meal) + tableView.insertRows(at: [newIndexPath], with: .automatic) + } } } diff --git a/iOSTemplate/MealViewController.swift b/iOSTemplate/MealViewController.swift index 3586d76..b68fb0d 100644 --- a/iOSTemplate/MealViewController.swift +++ b/iOSTemplate/MealViewController.swift @@ -27,6 +27,14 @@ class MealViewController: UIViewController, UITextFieldDelegate, UIImagePickerCo // Handle the text field’s user input through delegate callbacks. nameTextField.delegate = self + // Set up views if editing an existing Meal. + if let meal = meal { + navigationItem.title = meal.name + nameTextField.text = meal.name + photoImageView.image = meal.photo + ratingControl.rating = meal.rating + } + // Enable the Save button only if the text field has a valid Meal name. updateSaveButtonState() } @@ -72,7 +80,18 @@ class MealViewController: UIViewController, UITextFieldDelegate, UIImagePickerCo // MARK: Navigation @IBAction func cancel(_ sender: UIBarButtonItem) { - dismiss(animated: true, completion: nil) + // Depending on style of presentation (modal or push presentation), this view controller needs to be dismissed in two different ways. + let isPresentingInAddMealMode = presentingViewController is UINavigationController + + if isPresentingInAddMealMode { + dismiss(animated: true, completion: nil) + } + else if let owningNavigationController = navigationController{ + owningNavigationController.popViewController(animated: true) + } + else { + fatalError("The MealViewController is not inside a navigation controller.") + } } // This method lets you configure a view controller before it's presented. -- GitLab