Customizing the background/border colors of a UITableView (grouped style)
Customizing the background color of a UITableView is somewhat easy, but only if you use the plain style. If you use the grouped style of a table view, it starts to get way more complex. There are no easy ways to quickly set a property for the border color and the background color of the whole table view cell. Well, there are, but if you try to change some of these values and try to use the grouped style, it will look completely wrong.
Below you have a proper grouped table view using the standard Apple theme:
Looks pretty good, and it is also very simple to build that in objective-c. Assuming you use Interface Builder for your UI work, just set the table view as a “grouped”, and then set the title property of each cell, like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; } cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; NSArray *list = [NSArray arrayWithObjects:@"First", @"Second", @"Third", nil]; cell.text = [list objectAtIndex:indexPath.row]; return cell; } |
So now let’s try something tricky and simply change the backgroundColor property of cell.contentView, as that works fine when dealing with “plain” style table views. The code would be just a bit different:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; } cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; NSArray *list = [NSArray arrayWithObjects:@"First", @"Second", @"Third", nil]; cell.text = [list objectAtIndex:indexPath.row]; cell.contentView.backgroundColor = [UIColor redColor]; return cell; } |
And this is what it looks like:
At first I thought about changing cell.backgroundView, but that doesn’t work. So you can see that changing the contentView doesn’t work either, and it actually breaks a bunch of things:
- No rounded corners on the left side of the table view anymore
- The background color on the disclosure image is still set to white
- How do we change the border color anyway?
So after researching this problem for a while, and asking around for a solution, it seemed like there was no way to customize this stuff without a lot of manual work. Indeed that was the case, but Mike Akers (another StackOverflow.com member) posted the source code to a solution that he came up with, and that works very well so far. You can see his source code here for a custom background view with a border.
Here it is a modified version of my code to use his class:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; } cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; UILabel *label = [[[UILabel alloc] init] autorelease]; label.font = [UIFont boldSystemFontOfSize:16.0f]; label.frame = CGRectMake(40.0f, 10.0f, 220.0f, 22.0f); label.textColor = [UIColor whiteColor]; label.backgroundColor = [UIColor clearColor]; label.opaque = NO; NSArray *list = [NSArray arrayWithObjects:@"First", @"Second", @"Third", nil]; label.text = [list objectAtIndex:indexPath.row]; [cell.contentView addSubview:label]; CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero]; if (indexPath.row == 0) { bgView.position = CustomCellBackgroundViewPositionTop; } else if (indexPath.row == 1) { bgView.position = CustomCellBackgroundViewPositionMiddle; } else { bgView.position = CustomCellBackgroundViewPositionBottom; } cell.backgroundView = bgView; cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"more_arrow.png"]]; return cell; } |
And the resulting interface:
Ugly colors, but you get the idea. The code is also way more complex than before, but at least it’s possible to customize the background and border colors of a table view cell. This is more or less what we use on Knee Cap, our iPhone app that handles day to day money loans. This is what our custom table view looks like: