iOS Recipes - Matt Drance [39]
enum PRPFavoritesRows {
PRPTableSecFavoritesRowTeam = 0,
PRPTableSecFavoritesRowCity,
PRPTableSecFavoritesRowColor,
PRPTableSecFavoritesNumRows,
};
Every piece of code in this class checks against the enum declaration, so now City comes before Color in all our rows, and all the behavior—cell creation, selection, height, background, editing style—still matches up. The beautiful thing is that we didn’t need to touch or even look at any of it.
What if you want to remove the City row altogether? Easy: move it to the end of the enum, below PRPTableSecFavoritesNumRows, or just comment it out. We have simultaneously removed the City row from the usable list and decreased the total number of rows, with no other code changes. All the logic to create and handle the City row are still there, but it will just never be hit. It’s hard to believe, but try it. We’ve now made a risk-free change to our design that we can change right back in seconds. No more copies, pastes, undos, or source control reverts.
There’s something else going on here. The project uses multiple cell styles; where are the cell identifiers? The ‑dequeueReusableCellWithIdentifier: messages? They’re hidden away in PRPSmartTableViewCell subclasses, building on the earlier Recipe 15, Simplify Table Cell Production . Think about how much more code there would be without employing this additional technique, especially as the table’s complexity increases.
With this recipe, we’ve shown you a technique for writing a complex table view in a way that won’t make your head spin when you come back to it six months later. We hope it will also reduce the amount of work you need to do when it’s time to change things up.
Recipe 19 Produce Two-Tone Table Views
Problem
You like the two-tone appearance of the App Store and other apps, but UITableView lets you set only a single background color. How do you produce a smooth, easy table with different colors for the top and bottom?
Solution
UITableView offers an incredible amount of customization through its data source and delegate protocol methods, its header and footer views, and the versatile UITableViewCell. None of these options, however, gets us a table with different “background” colors on each end. To do this, we’ll write a clever UITableView subclass that’s also easy to reuse and customize. Figure 22, Two-tone table view layout illustrates the effect this recipe produces.
The solution we’re seeking displays different colors at either end of the table, as illustrated in these two screenshots. The table has a white gradient on top and a red background on the bottom. A traditional table view displays only a single background color beyond the top and bottom content edges.
(Please don’t ship an app with clashing colors like this. We’re only using them here to make the contrast obvious.)
Figure 22. Two-tone table view layout
* * *
Let’s look at the problem first. We can set the backgroundColor property on a table view easily enough, which colors the empty space that appears while scrolling beyond the table’s bounds. However, backgroundColor also affects the color of the table cells by default, so that’s not an ideal solution. We can view this effect by running the TwoToneTables project and tapping the Custom Background row.
So, how do we make the top a slightly different color from the rest of the table? That’s easy: we just set a table header. We can do this using a special PRPGradientView class that exposes the handy capabilities of CAGradientLayer. Now our header makes a smooth transition from the main background color to a slightly darker color up top.
TwoToneTables/Classes/DemoTableViewController.m
- (void)installHeader {
CGRect headerFrame = CGRectMake(0, 0, self.tableView.frame.size.width,
50.0);
PRPGradientView *header = [[PRPGradientView alloc]
initWithFrame:headerFrame];
[header setGradientColors:[NSArray arrayWithObjects:
(id)[self altBackgroundColor].CGColor,
(id)self.tableView.backgroundColor.CGColor,
nil]];
self.tableView.tableHeaderView = header;