[ios] How to customize the background color of a UITableViewCell?

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?

This question is related to ios iphone uitableview cocoa-touch background-color

The answer is


Subclass UITableViewCell and add this in the implementation:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.backgroundColor = [UIColor blueColor];
}

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.


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!


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.


Try this:

- (void)tableView:(UITableView *)tableView1 willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [cell setBackgroundColor:[UIColor clearColor]];
    tableView1.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"Cream.jpg"]];
}

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


Try this:

- (void)tableView:(UITableView *)tableView1 willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [cell setBackgroundColor:[UIColor clearColor]];
    tableView1.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"Cream.jpg"]];
}

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;
}

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.


    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];

This will work in the latest Xcode.

-(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
    cell.backgroundColor = [UIColor grayColor];
}

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.


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];
    }
}

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 ];
}

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.


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];

Subclass UITableViewCell and add this in the implementation:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.backgroundColor = [UIColor blueColor];
}

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!


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.


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.


This will work in the latest Xcode.

-(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
    cell.backgroundColor = [UIColor grayColor];
}

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 ];
}

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.


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 ];
}

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;
    }

}

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.


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.


    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];

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];

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


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 ];
}

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];
    }
}

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;
}

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.


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;
    }

}

Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to iphone

Detect if the device is iPhone X Xcode 8 shows error that provisioning profile doesn't include signing certificate Access files in /var/mobile/Containers/Data/Application without jailbreaking iPhone Certificate has either expired or has been revoked Missing Compliance in Status when I add built for internal testing in Test Flight.How to solve? cordova run with ios error .. Error code 65 for command: xcodebuild with args: "Could not find Developer Disk Image" Reason: no suitable image found iPad Multitasking support requires these orientations How to insert new cell into UITableView in Swift

Examples related to uitableview

Adding a UISegmentedControl to UITableView make UITableViewCell selectable only while editing How to fix Error: this class is not key value coding-compliant for the key tableView.' UITableView example for Swift Swift - how to make custom header for UITableView? How to insert new cell into UITableView in Swift How to detect tableView cell touched or clicked in swift Dynamic Height Issue for UITableView Cells (Swift) UIButton action in table view cell How to get the indexpath.row when an element is activated?

Examples related to cocoa-touch

Include of non-modular header inside framework module Move textfield when keyboard appears swift Create space at the beginning of a UITextField Navigation bar with UIImage for title Generate a UUID on iOS from Swift How do I write a custom init for a UIView subclass in Swift? creating custom tableview cells in swift How would I create a UIAlertView in Swift? Get current NSDate in timestamp format How do you add an in-app purchase to an iOS application?

Examples related to background-color

SwiftUI - How do I change the background color of a View? How to add a color overlay to a background image? How to change the background color on a input checkbox with css? How to change DatePicker dialog color for Android 5.0 Set Background color programmatically How to change the background-color of jumbrotron? Set textbox to readonly and background color to grey in jquery Change the background color of a pop-up dialog Background color of text in SVG Change background color of iframe issue