How to customize the background color of a UITableViewCell?
Asked Answered
L

18

191

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?

Lechner answered 11/11, 2008 at 17:11 Comment(0)
F
197

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.

Fraley answered 11/11, 2008 at 18:13 Comment(4)
e.g. myCell.contentView.backgroundColor = [ UIColor greenColor ];Stirpiculture
vlado.grigorov's answer is more flexible - see William Denniss' answerStirpiculture
Any links on how to roll one's own of UITableViewCellAccessoryCheckmark, for instance? Thanks.Retention
To see it sometimes you need to set: cell.textLabel.backgroundColor = [UIColor clearColor];Paynim
B
206

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...

Bellwether answered 3/8, 2009 at 7:2 Comment(5)
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.Kuibyshev
Indeed, and this is the method Apple themselves recommend according to various WWDC presentations I have seen.Ropeway
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...Rolland
This seems to work well, except when using Core Data. New cells added via an NSFetchedResultsController do not seem to call willDisplayCell properly. I am at a loss making it work...Thunderbolt
The equivalent line for setting background color in Swift 2.0: cell.backgroundColor = UIColor.clearColorRadix
F
197

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.

Fraley answered 11/11, 2008 at 18:13 Comment(4)
e.g. myCell.contentView.backgroundColor = [ UIColor greenColor ];Stirpiculture
vlado.grigorov's answer is more flexible - see William Denniss' answerStirpiculture
Any links on how to roll one's own of UITableViewCellAccessoryCheckmark, for instance? Thanks.Retention
To see it sometimes you need to set: cell.textLabel.backgroundColor = [UIColor clearColor];Paynim
B
105

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!

Barsky answered 10/5, 2010 at 13:57 Comment(3)
This should be marked as the correct answer as you dont even have to anything if you have a disclosureIndiatorGlinys
This doesn't work if you want a different cell background colour to the table views background for me.Vietcong
For group cell, you can set it on cellForRowKirkcudbright
T
59

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 ];
}
Thankyou answered 14/11, 2008 at 14:31 Comment(4)
If you do this, make sure to set the opaque property to NO as well.Berstine
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.Ropeway
On iOS 4.2 and later it looks like the loop is no longer necessary.Krak
Very nice. Works perfect when using accessory views!!Eggplant
D
19

Simply put this in you UITableView delegate class file (.m):

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell  forRowAtIndexPath:(NSIndexPath *)indexPath 
{
    UIColor *color = ((indexPath.row % 2) == 0) ? [UIColor colorWithRed:255.0/255 green:255.0/255 blue:145.0/255 alpha:1] : [UIColor clearColor];
    cell.backgroundColor = color;
}
Dollop answered 17/4, 2010 at 10:3 Comment(0)
G
7

I concur with Seba, I tried to set my alternating row color in the rowForIndexPath delegate method but was getting inconsistent results between 3.2 and 4.2. The following worked great for me.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    if ((indexPath.row % 2) == 1) {
        cell.backgroundColor = UIColorFromRGB(0xEDEDED);
        cell.textLabel.backgroundColor = UIColorFromRGB(0xEDEDED);
        cell.selectionStyle = UITableViewCellSelectionStyleGray;
    }
    else
    {
        cell.backgroundColor = [UIColor whiteColor];
        cell.selectionStyle = UITableViewCellSelectionStyleGray;
    }

}
Grillo answered 6/12, 2010 at 15:1 Comment(1)
Still do not understand why setting it in willDisplayCell makes any difference. It's called anyway whether we implement that or not right?Kirkcudbright
Y
6

After trying out all different solutions, the following method is the most elegant one. Change the color in the following delegate method:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (...){
        cell.backgroundColor = [UIColor blueColor];
    } else {
        cell.backgroundColor = [UIColor whiteColor];
    }
}
Yand answered 8/6, 2013 at 9:43 Comment(0)
F
4

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.

Faience answered 4/3, 2009 at 6:10 Comment(2)
An advantage to this approach is that you can keep the color a design time property in Interface Builder. One less design issue that requires developer interaction.Sacerdotalism
cell.backgroundView = [[[UIView alloc] initWithFrame: cell.bounds ] autorelease]; cell.backgroundView.backgroundColor = [UIColor redColor];Obligor
G
3

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.

Gennie answered 11/11, 2008 at 21:32 Comment(2)
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.Fraley
Ben - good point. I primarily use grouped tables but as you mention plain tables don't suffer from any of these problems.Gennie
J
3

Create a view and set this as background view of the cell

UIView *lab = [[UIView alloc] initWithFrame:cell.frame];
            [lab setBackgroundColor:[UIColor grayColor]];
            cell.backgroundView = lab;
            [lab release];
Judgemade answered 28/9, 2011 at 10:32 Comment(0)
A
3

To extend on N.Berendt's answer - If you want to set cell color based on some state in the actual cell data object, at the time you are configuring the rest of the information for the table cell, which is typically when you are in the cellForRowAtIndexPath method, you can do this by overriding the willDisplayCell method to set the cell background color from the content view background color - this gets around the issue of the disclosure button backgrounds etc. not being right but still lets you control color in the cellForRowAtIndexPath method where you are doing all of your other cell customisation.

So: If you add this method to your table view delegate:

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

Then in your cellForRowAtIndexPath method you can do:

if (myCellDataObject.hasSomeStateThatMeansItShouldShowAsBlue) {
    cell.contentView.backgroundColor = [UIColor blueColor];
}

This saves having to retrieve your data objects again in the willDisplayCell method and also saves having two places where you do tailoring/customisation of your table cell - all customisation can go in the cellForRowAtIndexPath method.

Alexis answered 2/2, 2012 at 1:8 Comment(0)
C
3

Create an image to use as background with Photoshop or gimp and name it myimage. Then, add this method to your tableViewController class:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    UIImage *cellImage = [UIImage imageNamed:@"myimage.png"];//myimage is a 20x50 px with  gradient  color created with gimp
    UIImageView *cellView = [[UIImageView alloc] initWithImage:cellImage];
    cellView.contentMode = UIContentViewModeScaleToFill;
    cell.backgroundView = cellView;
    //set the background label to clear
    cell.titleLabel.backgroundColor= [UIColor clearColor];
}

This will work also if you have set the UITableView to custom in attribute inspector.

Celaeno answered 25/2, 2013 at 21:12 Comment(0)
S
2

My solution is to add the following code to the cellForRowAtIndexPath event:

UIView *solidColor = [cell viewWithTag:100];
if (!solidColor) {

    solidColor = [[UIView alloc] initWithFrame:cell.bounds];
    solidColor.tag = 100; //Big tag to access the view afterwards
    [cell addSubview:solidColor];
    [cell sendSubviewToBack:solidColor];
    [solidColor release];
}
solidColor.backgroundColor = [UIColor colorWithRed:254.0/255.0
                                             green:233.0/255.0
                                              blue:233.0/255.0
                                             alpha:1.0];

Works under any circumstances, even with disclosure buttons, and is better for your logic to act on cells color state in cellForRowAtIndexPath than in cellWillShow event I think.

Scutage answered 7/2, 2011 at 13:56 Comment(0)
E
1

Subclass UITableViewCell and add this in the implementation:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.backgroundColor = [UIColor blueColor];
}
Eadith answered 6/12, 2012 at 21:32 Comment(0)
I
1
    UIView *bg = [[UIView alloc] initWithFrame:cell.frame];
    bg.backgroundColor = [UIColor colorWithRed:175.0/255.0 green:220.0/255.0 blue:186.0/255.0 alpha:1]; 
    cell.backgroundView = bg;
    [bg release];
Ioved answered 4/4, 2013 at 8:55 Comment(0)
F
1

This will work in the latest Xcode.

-(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
    cell.backgroundColor = [UIColor grayColor];
}
Fernferna answered 20/4, 2017 at 7:15 Comment(0)
R
0

Try this:

- (void)tableView:(UITableView *)tableView1 willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [cell setBackgroundColor:[UIColor clearColor]];
    tableView1.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"Cream.jpg"]];
}
Rootless answered 19/10, 2015 at 5:8 Comment(0)
S
-1

If we can override your cell class, you can try this approach

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    selectionStyle = .none
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)
    backgroundColor = selected ? .red : .clear
}
Symptom answered 9/6, 2022 at 10:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.