views:

21858

answers:

9

I would like to customize the background (and maybe the border too) of all of the UITableViewCells within my UITableView. So far I have not been able to customize this stuff, so I have a bunch of white background cells which is the default.

Is there a way to do this with the iPhone SDK?

+9  A: 

You need to set the backgroundColor of the cell's contentView to your color. If you use accessories (such as disclosure arrows, etc), they'll show up as white, so you may need to roll custom versions of those.

Ben Gottlieb
e.g. myCell.contentView.backgroundColor = [ UIColor greenColor ];
JoBu1324
vlado.grigorov's answer is more flexible - see William Denniss' answer
JoBu1324
+1  A: 

Customizing the background of a table view cell eventually becomes and "all or nothing" approach. It's very difficult to change the color or image used for the background of a content cell in a way that doesn't look strange.

The reason is that the cell actually spans the width of the view. The rounded corners are just part of its drawing style and the content view sits in this area.

If you change the color of the content cell you will end up with white bits visible at the corners. If you change the color of the entire cell, you will have a block of color spanning the width of the view.

You can definitely customize a cell, but it's not quite as easy as you may think at first.

Andrew Grant
This is definitely true for cells in Grouped tables, but Plain tables don't have as much to worry about. An unadorned cell with no accessories should look fine.
Ben Gottlieb
Ben - good point. I primarily use grouped tables but as you mention plain tables don't suffer from any of these problems.
Andrew Grant
+21  A: 

The best approach I've found so far is to set a background view of the cell and clear background of cell subviews. Of course, this looks nice on tables with indexed style only, no matter with or without accessories.

Here is a sample where cell's background is panted yellow:

UIView* backgroundView = [ [ [ UIView alloc ] initWithFrame:CGRectZero ] autorelease ];
backgroundView.backgroundColor = [ UIColor yellowColor ];
cell.backgroundView = backgroundView;
for ( UIView* view in cell.contentView.subviews ) 
{
    view.backgroundColor = [ UIColor clearColor ];
}
Vladimir Grigorov
If you do this, make sure to set the opaque property to NO as well.
Kevin Ballard
Using transparent cell controls is really not recommended. The scrolling performance will be affected a lot which is why Apple always says to use opaque controls.
Mike Weller
+1 Best answer to take into consideration of the accessory views
DonnaLea
+2  A: 

vlado.grigorov has some good advice - the best way is to create a backgroundView, and give that a colour, setting everything else to the clearColor. Also, I think that way is the only way to correctly clear the colour (try his sample - but set 'clearColor' instead of 'yellowColor'), which is what I was trying to do.

William Denniss
+19  A: 

Here is the most efficient way I have come across to solve this problem, use the willDisplayCell delegate method (this takes care of the white color for the text label background as well when using cell.textLabel.text and/or cell.detailTextLabel.text):

  • (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { ... }

When this delegate method is called the color of the cell is controlled via the cell rather than the table view, as when you use:

  • (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath { ... }

So within the body of the cell delegate method add the following code to alternate colors of cells or just use the function call to make all the cells of the table the same color.

if (indexPath.row % 2)
{
 [cell setBackgroundColor:[UIColor colorWithRed:.8 green:.8 blue:1 alpha:1]];
}
else [cell setBackgroundColor:[UIColor clearColor]];

This solution worked well in my circumstance...

N.Berendt
Great solution. Thanks!
CalebHC
This is a way cleaner solution. Most of the other solutions require either subclassing the UITableViewCell. vlado.grigorov's solution don't work for me.
Ronnie Liew
Indeed, and this is the method Apple themselves recommend according to various WWDC presentations I have seen.
Mike Weller
Nice - EXCEPT when you need to add new rows at top of the list. This method make all additions same color. Refresh does fix it, but takes unnecessary time. Found out yesterday...
JOM
A: 

How do I change the target UITableView's cell's background per user's touch (rather than the default blue)?

  • (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [theTableView cellForRowAtIndexPath:indexPath]; cell.contentView.backgroundColor = [UIColor redColor]; // e.g., want red vs blue.

    [cell.contentView setNeedsDisplay];

    [theTableView deselectRowAtIndexPath:indexPath animated:NO]; DJMyJournalFolderCellController *controller = [self.feedItems objectAtIndex:indexPath.row]; DJNewsSectionViewController *viewController = [[DJNewsSectionViewController alloc] initWithNibName:@"RSSViewController" bundle:nil]; viewController.section = controller.item;

    [[self navigationController] pushViewController:viewController animated:YES];

    [viewController release];

}

I tried to force the cell to re-display with [ setNeedsDisplay] but it doesn't work.

Ric.

A: 

if (indexPath.row % 2) { [cell setBackgroundColor:[UIColor colorWithRed:.8 green:.8 blue:1 alpha:1]]; } else [cell setBackgroundColor:[UIColor clearColor]];

The above code by N.Berendt works good. I have used it.

But I have one problem. (not with the above code, but with a sceanrio I have)

In case of a "selected cell", how would you change the background color? Say I have a list of 10 cells for mainmenu. And I am trying to change the background color for one selected cell.

sg
Have you tried: [cell setSelectedBackgroundView:(UIView *)]
Jason Moore
+2  A: 
JAG
+6  A: 

This is really simple, since OS 3.0 just set the background color of the cell in the willDisplayCell method. You must not set the color in the cellForRowAtIndexPath.

This works for both the plain and grouped style :

Code:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = [UIColor redColor];
}

P.S: Here the documentation extract for willDisplayCell :

"A table view sends this message to its delegate just before it uses cell to draw a row, thereby permitting the delegate to customize the cell object before it is displayed. This method gives the delegate a chance to override state-based properties set earlier by the table view, such as selection and background color. After the delegate returns, the table view sets only the alpha and frame properties, and then only when animating rows as they slide in or out."

I've found this information in this post from colionel. Thank him!

Seba