Responding to cell-selection

Cell-selection refers to a user tapping on a cell. In order to respond to cell-selection, the UITableViewDelegate method called tableView(_:didSelectRowAt:) should be implemented. In Hello-ContactsViewController already has an extension implemented to make it conform to UITableViewDelegate so all you need to do is implement tableView(_:didSelectRowAt:) in the extension.

Since a table view will call methods on its delegate whenever they are implemented, you don't need to tell the table view that you want to respond to cell-selection. This automatically works if the table view has a delegate, and if the delegate implements tableView(_:cellForRowAt:). The implementation you'll add to Hello-Contacts, for now, is a very simple one. When the user taps a cell, the app displays an alert. In Chapter 3, Creating a Detail Page, you will learn how to perform more meaningful actions such as displaying a detail page. Add the following code to the UITableViewDelegate extension in ViewController.swift:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  let contact = contacts[indexPath.row]
  let alertController = UIAlertController(title: "Contact tapped",
                                          message: "You tapped (contact.givenName)",
                                          preferredStyle: .alert)

  let dismissAction = UIAlertAction(title: "Ok", style: .default, handler: { action in
    tableView.deselectRow(at: indexPath, animated: true)
  })

  alertController.addAction(dismissAction)
  present(alertController, animated: true, completion: nil)
}

The tableView(_:cellForRowAt:) method receives two arguments, the first is the table view that called this delegate method. The second argument is the index path at which the selection occurred. The implementation you wrote for this method uses the index path to retrieve the contact that corresponds with the tapped cell so the contact name can be shown in an alert. You could also retrieve the contact's name from the tapped cell. However, this is not considered good practice because your cells and the underlying data should be as loosely-coupled as possible. When the user taps the Ok button in the alert, the table view is told to deselect the selected row. If you don't deselect the selected row, the last tapped cell will always remain highlighted. Note that the alert is displayed by calling present(_:animated:completion:) on the view controller. Any time you want to make a view controller display another view controller, such as an alert controller, you use this method.

Even though this setup is not extremely complex, there is some interesting stuff going on. The delegation pattern is a very powerful one when implemented correctly. Especially in the case of a table view, you can add a lot of functionality simply by implementing the delegate methods that correspond to the desired behavior. Because the table view's delegate could be any object that conforms to UITableViewDelegate, you could split up ViewController and UITableViewDelegate entirely. Doing so would enable you to reuse your delegate implementation across multiple table views. For now, I'll leave it as an exercise for you to do this. Attempting such a refactor will certainly help you to increase your understanding of delegation and its powers.

Try to extract your delegate and/or data source for the table view to a separate class or struct. This will allow you to reuse your code, and you will gain a deeper understanding of what delegation is and how it works.
..................Content has been hidden....................

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