Interacting with UITableViews
Currently our AlphabetController is the dataSource of the table, but remember how tables also have a delegate? We need to make our controller the delegate if we want it to respond when someone taps the row.
The table view’s dataSource methods are generally about supplying information to a table; the delegate methods concern themselves with what happens after the table is set up and how the user interacts with it. We’ll use one of these delegate methods to push a new view controller when a row is tapped.
We start by making our controller the delegate in viewDidLoad, just like dataSource.
|||@table.dataSource = self|
|»||@table.delegate = self|
There aren’t any required methods of a table’s delegate; you’re free to implement any (or none) depending on what you need. We’re going to use the tableView:didSelectRowAtIndexPath: method to figure out when a row was tapped by the user, like so:
|||def tableView(tableView, didSelectRowAtIndexPath:indexPath)|
|||tableView.deselectRowAtIndexPath(indexPath, animated: true)|
|||letter = @data[indexPath.row]|
|||controller = UIViewController.alloc.initWithNibName(nil, bundle:nil)|
|||controller.view.backgroundColor = UIColor.whiteColor|
|||controller.title = letter|
|||label = UILabel.alloc.initWithFrame(CGRectZero)|
|||label.text = letter|
|||label.center = [controller.view.frame.size.width / 2,|
|||controller.view.frame.size.height / 2]|
We need to use deselectRowAtIndexPath:animated: because by default UITableView will keep a row highlighted in blue once the user taps it. After that, we construct a basic UIViewController with a label for our letter and push it onto the stack.
At this point, our example works, but it’s missing one subtle interface element: the right-pointing gray chevron on our table rows. These arrows are used to indicate that tapping a row will push a new controller. These icons and any other UIView are referred to as the table cell’s accessory. iOS includes some accessories like the gray chevron, but we can assign arbitrary views for each cell.
Let’s head back to tableView:cellForRowAtIndexPath: to assign each cell the UITableViewCellAccessoryDisclosureIndicator accessory. That is a long variable name, isn’t it?
|||cell = tableView.dequeueReusableCellWithIdentifier(@reuseIdentifier)|
|»||cell ||= UITableViewCell.alloc.initWithStyle(|
|»||cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator|
Great! Let’s give our app a whirl and move around! Our table should look like this:
We haven’t written a ton of code, but already it is a very familiar (and fast) interface. Much like Mailapp, we can tap table rows and dig deeper into a detail controller. But there’s another common interface element missing from this example: sections.