The Shopping List Table View Controller
As you may have guessed, we need a new View Controller to get our app to work. This will be called ShoppingListTableViewController and it will be very similar to ItemTableViewController. This new Shopping List View Controller will be our Root View Controller and it will list all of our Shopping Lists. On tapping one of those lists, it will push a new Item View Controller into the navigation and list all of the items in that shopping list. To get started:
- Create a new Table View Controller file in the Controllers folder by right-clicking on the folder and selecting New File....
- Select Cocoa Touch Class and Subclass it from BaseTableViewController, then call the ShoppingListTableViewController file.
- Copy the following code into the new ShoppingListTableViewController.swift file. This file has the same methods defined as in ItemTableViewController, but it also has few extra methods to pass the selected list to ItemTableViewController on selection of a list:
import UIKit
class ShoppingListTableViewController: BaseTableViewController {
var lists: [ShoppingList] = [ShoppingList].load() {
didSet {
lists.save()
}
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Shopping Lists"
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.rightBarButtonItems?.append(editButtonItem)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func didSelectAdd(_ sender: UIBarButtonItem) {
requestInput(title: "Shopping list name",
message: "Enter name for the new shopping list:",
handler: { (listName) in
let listCount = self.lists.count;
let list = ShoppingList(name: listName, items: [], onUpdate: self.lists.save)
self.lists.append(list)
self.tableView.insertRows(at: [IndexPath(row: listCount, section: 0)], with: .top)
})
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lists.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell", for: indexPath)
let list = lists[indexPath.row]
cell.textLabel?.text = list.name
return cell
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
lists.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
lists.swapAt(fromIndexPath.row, to.row)
}
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destinationViewController = segue.destination as? ItemTableViewController {
if let indexPath = self.tableView.indexPathForSelectedRow {
let list = lists[indexPath.row]
destinationViewController.list = list
}
}
}
}
If we build our app, it should compile without any errors, but it will not work and that's because we haven't updated our storyboard to start our application with the ShoppingListTableViewController. This is fairly easy to do. All we need to do is take the following steps:
- Open Main.storyboard and drag a new Table View Controller into the board:
- Select the new Table View Controller. Under Custom Class, change the Class to ShoppingListTableViewController:
- Press Control and drag it from the Navigation Controller to the Shopping List Table View Controller and select the Relationship Segue as the Root View Controller:
- Inside the Shopping List Table View Controller, click on the Table View Cell, change the Style under Attribute Inspector to Basic, Accessory to Disclosure Indicator, and in the Identifier field, enter ListCell:
- Press control again and now drag from the Table View Cell of the Shopping List Controller to the Root View Controller, which is our Item View Controller, and select Show from the Selection Segue:
- Just like the Item View Controller, drag the Bar Button Item, add it to the right side of the Shopping List Controller's navigation bar, and change the System Item to Add:
- Press control and drag the Add (+) Bar Button from the navigation bar of the Shopping List Controller and drag it to the Shopping List Table View Controller, on the left side of the Storyboard and under Sent Actions select didSelectAdd:
Run the app and everything should work, now we have multiple Shopping Lists in our application. We can dive into one of these Shopping Lists and add, delete, rearrange the items in that Shopping List and even delete the entire Shopping List itself. Modifying any of the Shopping Lists should save them in our app: