Today I present a simple design technique that can make your UITableViewControllers
a lot more flexible. To put it concisely: You should use indirection when considering section indices in your flow-of-control. This technique makes section re-ordering much easier, and may in fact be necessary to make such re-ordering practical at all. I explain more below.
Sections
It’s pretty common to break a table into sections, and to assign different behaviors (especially editing behaviors) to each section. The naive way to do this is to switch on the section
property of an indexPath
(or the section
argument of a UITableViewDataSource
or UITableViewDelegate
method). For example, this code sets the section header text for a two section table:
- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section
{
switch (section)
{
case 0:
return @"Primary Fields";
case 1:
return @"Optional Fields";
default:
return nil;
}
}
Reordering
The problem with this approach can be seen if you consider what happens when you remove (or add, or re-order) sections in the table. The naive approach hard-codes a section’s behavior to a particular position/index in the table. If, for instance, you wanted to display the optional fields first, you’d be out of luck.
Indirection
The solution is to add a look-up table that maps a section’s index to its type. Assuming that your view controller stores such a table in an NSArray*
called sections
, you might recode the previous function like this:
- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section
{
section = [[self.sections objectAtIndex:section] integerValue];
switch (section)
{
case SectionTypePrimary:
return @"Primary Fields";
case SectionTypeOptional:
return @"Optional Fields";
default:
return nil;
}
}
where the section types are defined in an enum
, as for instance:
enum SectionType
{
SectionTypePrimary = 0,
SectionTypeOptional = 1,
};
Using this approach, re-ordering the sections is (almost) just a matter of changing the contents of sections
.
Not Rocket Science
I suppose that none of this is particularly insightful, but I wanted to bring it up for several reasons:
- Indirection requires only a few more lines of code in your controller than the naive approach.
- However, recoding an existing naive controller to use indirection is a nuisance, given the large number of constants that must be changed.
- Therefore, it pays to use indirection up front in all your
UITableViewControllers
. - The significance of these facts escaped my notice while I was coding up several relatively complex view controllers; as a result, I wasted a non-neglible amount of time. I’d like to save someone else from the same mistake.