Online Book Reader

Home Category

iOS Recipes - Matt Drance [37]

By Root 224 0
Complex Table Views

Credit

This recipe was inspired in no small part by Fraser Speirs’ excellent article, “A technique for using UITableView and retaining your sanity,” at speirs.org.

Problem

Working with UITableView is easy when you have a uniform dataset. Once you need to do something special in a particular section or row, however, things can get out of hand quickly. How can you cleanly build a table view with diverse rows, like the one seen in the Settings application?

Solution

This kind of problem can sneak up on us. Let’s say we have some in-app settings to manage or a few high-level navigation options that are always present. We start with a simple table with identical rows for each of the choices. Easy enough: create an array for the intended titles and use that to build the table’s rows.

-(void)viewDidLoad {

self.rowTitles = [NSArray arrayWithObjects:@"Favorite Team",

@"Favorite Color",

@"Alerts", nil];

}

- (NSInteger)numberOfSectionsInTableView:(UITableView)tableView {

return 1;

}

- (NSInteger)tableView:(UITableView)tableView

numberOfRowsInSection:(NSInteger)section {

return [self.rowTitles count];

}

Looks good, right? We use the array to determine the number of rows and now just index the array in ‑tableView:cellForRowAtIndexPath: to get our cell titles.

cell.textLabel.text = [self.rowTitles objectAtIndex:indexPath.row];

So, each of these cells, when tapped, performs a completely different task. It’s not like Contacts, where we just present the person detail screen with the selected data. Each row will push its own unique detail interface. Now things get complicated, starting with ‑tableView:didSelectCellForRowAtIndexPath:.

switch (indexPath.row) {

case 0:

// Push the team selection view controller

break;

case 1:

// Push the color selection view controller

break;

case 2:

// Push the alerts view controller

break;

default:

NSLog(@"GAME OVER, MAN! GAME OVER!");

break;

}

The use of magic numbers here is an immediate red flag. We could declare constants to use here instead, but that’s really just masking the problem: our logic for creating the rows (a switch statement tied to literals) has been decoupled from our logic for setting them up (the array).

Let’s make things more complicated. Our designer tells us the alerts row should have a different appearance. Now we need to add a similar switch statement blob to ‑tableView:cellForRowAtIndexPath:, which until now was relatively clean. We may even be looking at multiple reuse identifiers to represent the new cell layouts.

It gets worse. We’ve decided that “favorite color” should come before “favorite team” in the list. Now we have to reorder your array and shuffle around every piece of code that checks the row index. Right now, that’s just cell creation and selection. What if we decide to customize the cell height? The background color? What if we have a table where some cells are editable and others aren’t? Each of these scenarios yields yet another data source or delegate method relying on this fragile technique. If we forget to change one area or type the wrong number, we end up with misplaced behavior or even exceptions because of an out-of-bounds index.

Unstructured data can be difficult to manage with UITableView. Note how each row in the first section is unique, and each section has an explicit number and order of rows.

Figure 21. Heterogeneous table view layout

* * *

Actually, scratch that: alerts should be in a different section. Now we need a two-dimensional switch statement—one for sections, one for rows—and a two-dimensional array for all the row titles. If we forget to increase the hard-coded number of sections, data will disappear. If we later reduce the number of sections, we have exposed ourselves to another out-of-bounds exception from stale indexing logic.

How did it come to this? Everything was so simple at first. The (allegedly) final design can be seen in Figure 21, Heterogeneous table view layout .

Your interface doesn’t always line up with a basic data structure where each row

Return Main Page Previous Page Next Page

®Online Book Reader