Adding Rows

There are two common interfaces for adding rows to a table view at runtime.

  • A button above the cells of the table view: usually for adding a record for which there is a detail view. For example, in the Contacts app, you tap a button when you meet a new person and want to take down his or her information.

  • A cell with a green plus sign: usually for adding a new field to a record, such as when you want to add a birthday to a person’s record in the Contacts app. In editing mode, you tap the green plus sign next to add birthday.

In this exercise, you will use the first option and create a New button in the header view. When this button is tapped, a new row will be added to the UITableView.

In ItemsViewController.swift, implement addNewItem(_:).

@IBAction func addNewItem(_ sender: UIButton) {
    // Make a new index path for the 0th section, last row
    let lastRow = tableView.numberOfRows(inSection: 0)
    let indexPath = IndexPath(row: lastRow, section: 0)

    // Insert this new row into the table
    tableView.insertRows(at: [indexPath], with: .automatic)
}

Build and run the application. Tap the Add button and … the application crashes. The console tells you that the table view has an internal inconsistency exception.

Remember that, ultimately, it is the dataSource of the UITableView that determines the number of rows the table view should display. After inserting a new row, the table view has six rows (the original five plus the new one). When the UITableView asks its dataSource for the number of rows, the ItemsViewController consults the store and returns that there should be five rows. The UITableView cannot resolve this inconsistency and throws an exception.

You must make sure that the UITableView and its dataSource agree on the number of rows by adding a new Item to the ItemStore before inserting the new row.

In ItemsViewController.swift, update addNewItem(_:).

@IBAction func addNewItem(_ sender: UIButton) {
    // Make a new index path for the 0th section, last row
    let lastRow = tableView.numberOfRows(inSection: 0)
    let indexPath = IndexPath(row: lastRow, section: 0)

    // Insert this new row into the table
    tableView.insertRows(at: [indexPath], with: .automatic)

    // Create a new item and add it to the store
    let newItem = itemStore.createItem()

    // Figure out where that item is in the array
    if let index = itemStore.allItems.index(of: newItem) {
        let indexPath = IndexPath(row: index, section: 0)

        // Insert this new row into the table
        tableView.insertRows(at: [indexPath], with: .automatic)
    }
}

Build and run the application. Tap the Add button, and the new row will slide into the bottom position of the table. Remember that the role of a view object is to present model objects to the user; updating views without updating the model objects is not very useful.

Now that you have the ability to add rows and items, you no longer need the code that puts five random items into the store.

Open ItemStore.swift and remove the initializer code.

init() {
    for _ in 0..<5 {
        createItem()
    }
}

Build and run the application. There will no longer be any rows when you first launch the application, but you can add some by tapping the Add button.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset