[ios] UITableView Cell selected Color?

I have created a custom UITableViewCell. The table view is showing data fine. What I am stuck in is when user touches cell of tableview, then I want to show the background color of the cell other than the default [blue color] values for highlighting the selection of cell. I use this code but nothing happens:

cell.selectedBackgroundView.backgroundColor=[UIColor blackColor];

This question is related to ios objective-c uitableview selection-color ui-select2

The answer is


1- Add a view to the content view of your cell.
2- Right click your cell.
3- Make the added view as "selectedBackgroundView".

enter image description here


-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIView *view = [[UIView alloc] init];
    [view setBackgroundColor:[UIColor redColor]];
    [cell setSelectedBackgroundView:view];
}

We need to set the selected background view in this method.


In Swift 4, you can also set the background color of your table cell globally (taken from here):

let backgroundColorView = UIView()
backgroundColorView.backgroundColor = UIColor.red
UITableViewCell.appearance().selectedBackgroundView = backgroundColorView

The following works for me in iOS 8.

I have to set the selection style to UITableViewCellSelectionStyleDefault for custom background color to work. If any other style, the custom background color will be ignored. There seems to be a change in behaviours as previous answers needs to set style to none instead.

The full code for the cell as follows:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"MyCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // This is how you change the background color
    cell.selectionStyle = UITableViewCellSelectionStyleDefault;
    UIView *bgColorView = [[UIView alloc] init];
    bgColorView.backgroundColor = [UIColor redColor];
    [cell setSelectedBackgroundView:bgColorView];        
    return cell;
}

Swift 3: for me it worked when you put it in the cellForRowAtIndexPath: method

let view = UIView()
view.backgroundColor = UIColor.red
cell.selectedBackgroundView = view

Try Following code.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[cellIdArray objectAtIndex:indexPath.row] forIndexPath:indexPath];

    // Configure the cell...
    cell.backgroundView =
    [[UIImageView alloc] init] ;
    cell.selectedBackgroundView =[[UIImageView alloc] init];

    UIImage *rowBackground;
    UIImage *selectionBackground;


    rowBackground = [UIImage imageNamed:@"cellBackgroundDarkGrey.png"];
    selectionBackground = [UIImage imageNamed:@"selectedMenu.png"];

    ((UIImageView *)cell.backgroundView).image = rowBackground;
    ((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;



    return cell;
}

//Swift Version:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")! as UITableViewCell


        cell.selectedBackgroundView = UIImageView()
        cell.backgroundView=UIImageView()

        let selectedBackground : UIImageView = cell.selectedBackgroundView as! UIImageView
        selectedBackground.image = UIImage.init(named:"selected.png");

        let backGround : UIImageView = cell.backgroundView as! UIImageView
        backGround.image = UIImage.init(named:"defaultimage.png");

        return cell


    } 

I'm using iOS 9.3 and setting the color through the Storyboard or setting cell.selectionStyle didn't work for me, but the code below worked:

UIView *customColorView = [[UIView alloc] init];
customColorView.backgroundColor = [UIColor colorWithRed:55 / 255.0 
                                                  green:141 / 255.0 
                                                   blue:211 / 255.0 
                                                  alpha:1.0];
cell.selectedBackgroundView = customColorView;

return cell;

I found this solution here.


Swift 4.x

To Change the selection background Colour to anyColour use Swift Extension

Create UITableView Cell extension as below

extension UITableViewCell{

    func removeCellSelectionColour(){
        let clearView = UIView()
        clearView.backgroundColor = UIColor.clear
        UITableViewCell.appearance().selectedBackgroundView = clearView
    } 

}

Then call removeCellSelectionColour() with cell instance.


To add the background for all cells (using Maciej's answer):

for (int section = 0; section < [self.tableView numberOfSections]; section++) {
        for (int row = 0; row < [self.tableView numberOfRowsInSection:section]; row++) {
            NSIndexPath* cellPath = [NSIndexPath indexPathForRow:row inSection:section];
            UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:cellPath];

            //stuff to do with each cell
            UIView *bgColorView = [[UIView alloc] init];
            bgColorView.backgroundColor = [UIColor redColor];
            [cell setSelectedBackgroundView:bgColorView];
        }
    } 

Use [cell setClipsToBounds:YES]; for Grouped style cell


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView reloadData];
    UITableViewCell *cell=(UITableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
    [cell setBackgroundColor:[UIColor orangeColor]];
}

Table View Cell selection background color can be set via the Storyboard in Interface Builder:

table view cell selection color None


[cell setSelectionStyle:UITableViewCellSelectionStyleGray];

Make sure you have used the above line to use the selection effect


If you have a grouped table with just one cell per section, just add this extra line to the code: bgColorView.layer.cornerRadius = 10;

UIView *bgColorView = [[UIView alloc] init];
[bgColorView setBackgroundColor:[UIColor redColor]];
bgColorView.layer.cornerRadius = 10;
[cell setSelectedBackgroundView:bgColorView];
[bgColorView release]; 

Don't forget to import QuartzCore.


As per custom color for a selected cell in UITableView, great solution as per Maciej Swic's answer

Just to add to that, you declare Swic's answer in the Cell configuration usually under:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

And for an added effect, instead of the system colors, you may use RGB values for a custom color look. In my code this is how I achieved it:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

} 

 static NSString *CellIdentifier = @"YourCustomCellName";
 MakanTableCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

// Configure the cell...

if (cell == nil) {

cell = [[[NSBundle mainBundle]loadNibNamed:@"YourCustomCellClassName" owner:self options:nil]objectAtIndex:0];
                    } 

UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor colorWithRed:255.0/256.0 green:239.0/256.0 blue:49.0/256.0 alpha:1];
bgColorView.layer.cornerRadius = 7;
bgColorView.layer.masksToBounds = YES;
[cell setSelectedBackgroundView:bgColorView];


return cell;

}

Let me know if that works for you as well. You can mess with the cornerRadius number for the effects on the corners of the selected cell.


In case of custom cell class. Just override:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state

    if (selected) {
        [self setBackgroundColor: CELL_SELECTED_BG_COLOR];
        [self.contentView setBackgroundColor: CELL_SELECTED_BG_COLOR];
    }else{
        [self setBackgroundColor: [UIColor clearColor]];
        [self.contentView setBackgroundColor: [UIColor clearColor]];
    }
}

for Swift 3.0:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = super.tableView(tableView, cellForRowAt: indexPath)

    cell.contentView.backgroundColor = UIColor.red
}

It's easy when the table view style is plain, but in group style, it's a little trouble, I solve it by:

CGFloat cellHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kGroupTableViewCellWidth+2, cellHeight)];
view.backgroundColor = kCommonHighlightedColor;
cell.selectedBackgroundView = view;
[view release];
UIRectCorner cornerFlag = 0;
CGSize radii = CGSizeMake(0, 0);
NSInteger theLastRow = --> (yourDataSourceArray.count - 1);
if (indexPath.row == 0) {
    cornerFlag = UIRectCornerTopLeft | UIRectCornerTopRight;
    radii = CGSizeMake(10, 10);
} else if (indexPath.row == theLastRow) {
    cornerFlag = UIRectCornerBottomLeft | UIRectCornerBottomRight;
    radii = CGSizeMake(10, 10);
}
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:cornerFlag cornerRadii:radii];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = maskPath.CGPath;
view.layer.mask = shapeLayer;

noted the kGroupTableViewCellWidth, I define it as 300, it's the width of group table view cell width in iPhone


Create a custom cell for your table cell and in the custom cell class.m put the code below, it will work fine. You need to place the desired color image in selectionBackground UIImage.

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    UIImage *selectionBackground = [UIImage imageNamed:@"yellow_bar.png"];
    UIImageView *iview=[[UIImageView alloc] initWithImage:selectionBackground];
    self.selectedBackgroundView=iview;
}

Swift 5 - Xcode version 12.1 (12A7403)

|Step One|
Add the following to your AppDelegate.swift file

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    let colorView = UIView()
    colorView.backgroundColor = UIColor.lightGray

    UITableViewCell.appearance().selectedBackgroundView = colorView
        
    return true
}

|Step Two|
Make sure your cell's Content View background is set to "Clear Color" (and not "Default") in the Attributes Inspector. This is done to not conflict with your App Delegate setting.


for those that just want to get rid of the default selected grey background put this line of code in your cellForRowAtIndexPath func:

yourCell.selectionStyle = .None

No need for custom cells. If you only want to change the selected color of the cell, you can do this:

Objective-C:

UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor redColor];
[cell setSelectedBackgroundView:bgColorView];

Swift:

let bgColorView = UIView()
bgColorView.backgroundColor = UIColor.red
cell.selectedBackgroundView = bgColorView

One more tip to Christian's way to show rounded corner background for grouped table.

If I use cornerRadius = 10 for cell, it shows four corner's rounded selection background. It's not the same with table view's default UI.

So, I think about easy way to resolve it with cornerRadius. As you can see from the below codes, check about cell's location (top, bottom, middle or topbottom) and add one more sub layers to hide top corner or bottom corner. This just shows exactly same look with default table view's selection background.

I tested this code with iPad splitterview. You can change patchLayer's frame position as you needed.

Please let me know if there is more easier way to achieve same result.

if (tableView.style == UITableViewStyleGrouped) 
{
    if (indexPath.row == 0) 
    {
        cellPosition = CellGroupPositionAtTop;
    }    
    else 
    {
        cellPosition = CellGroupPositionAtMiddle;
    }

    NSInteger numberOfRows = [tableView numberOfRowsInSection:indexPath.section];
    if (indexPath.row == numberOfRows - 1) 
    {
        if (cellPosition == CellGroupPositionAtTop) 
        {
            cellPosition = CellGroupPositionAtTopAndBottom;
        } 
        else 
        {
            cellPosition = CellGroupPositionAtBottom;
        }
    }

    if (cellPosition != CellGroupPositionAtMiddle) 
    {
        bgColorView.layer.cornerRadius = 10;
        CALayer *patchLayer;
        if (cellPosition == CellGroupPositionAtTop) 
        {
            patchLayer = [CALayer layer];
            patchLayer.frame = CGRectMake(0, 10, 302, 35);
            patchLayer.backgroundColor = YOUR_BACKGROUND_COLOR;
            [bgColorView.layer addSublayer:patchLayer];
        } 
        else if (cellPosition == CellGroupPositionAtBottom) 
        {
            patchLayer = [CALayer layer];
            patchLayer.frame = CGRectMake(0, 0, 302, 35);
            patchLayer.backgroundColor = YOUR_BACKGROUND_COLOR;
            [bgColorView.layer addSublayer:patchLayer];
        }
    }
}

Swift 4+:

Add following lines in your table cell

let bgColorView = UIView()
bgColorView.backgroundColor =  .red
self.selectedBackgroundView = bgColorView

Finally it should be as below

override func setSelected(_ selected: Bool, animated: Bool)
    {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
        let bgColorView = UIView()
        bgColorView.backgroundColor =  .red
        self.selectedBackgroundView = bgColorView

    }

If you want to add a custom highlighted color to your cell (and your cell contains buttons,labels, images,etc..) I followed the next steps:

For example if you want a selected yellow color:

1) Create a view that fits all the cell with 20% opacity (with yellow color) called for example backgroundselectedView

2) In the cell controller write this:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
     self.backgroundselectedView.alpha=1;
    [super touchesBegan:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.backgroundselectedView.alpha=0;
    [super touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.backgroundSelectedImage.alpha=0;
    [super touchesCancelled:touches withEvent:event];
}

Swift 3.0 extension

extension UITableViewCell {
    var selectionColor: UIColor {
        set {
            let view = UIView()
            view.backgroundColor = newValue
            self.selectedBackgroundView = view
        }
        get {
            return self.selectedBackgroundView?.backgroundColor ?? UIColor.clear
        }
    }
}

cell.selectionColor = UIColor.FormaCar.blue


I want to note that the XIB editor offers you the following standard options:

Section: blue/gray/none

(the right-hand column with options, 4th tab, first group "Table View Cell", 4th subgroup, the 1st of 3 items reads "Selection")

Probably what you want to do may be achieved by selecting the right standard option.


override func setSelected(selected: Bool, animated: Bool) {
    // Configure the view for the selected state

    super.setSelected(selected, animated: animated)
    let selView = UIView()

    selView.backgroundColor = UIColor( red: 5/255, green: 159/255, blue:223/255, alpha: 1.0 )
    self.selectedBackgroundView = selView
}

If you are using a custom TableViewCell, you can also override awakeFromNib:

override func awakeFromNib() {
    super.awakeFromNib()

    // Set background color
    let view = UIView()
    view.backgroundColor = UIColor.redColor()
    selectedBackgroundView = view
}

I've got a slightly different approach than everyone else that reflects the selection on touch rather than after being selected. I have a subclassed UITableViewCell. All you have to do is set the background color in the touch events, which simulates selection on touch, and then set the background color in the setSelected function. Setting the background color in the selSelected function allows for deselecting the cell. Make sure to pass the touch event to the super, otherwise the cell won't actually act as if its selected.

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    self.backgroundColor = UIColor(white: 0.0, alpha: 0.1)
    super.touchesBegan(touches, withEvent: event)
}

override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) {
    self.backgroundColor = UIColor.clearColor()
    super.touchesCancelled(touches, withEvent: event)
}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
    self.backgroundColor = selected ? UIColor(white: 0.0, alpha: 0.1) : UIColor.clearColor()
}

Here is the important parts of the code needed for a grouped table. When any of the cells in a section are selected the first row changes color. Without initially setting the cellselectionstyle to none there is an annonying double reload when the user clicks row0 where the cell changes to bgColorView then fades and reloads bgColorView again. Good Luck and let me know if there is a simpler way to do this.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    if ([indexPath row] == 0) 
    {
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        UIView *bgColorView = [[UIView alloc] init];
        bgColorView.layer.cornerRadius = 7;
        bgColorView.layer.masksToBounds = YES;
        [bgColorView setBackgroundColor:[UIColor colorWithRed:.85 green:0 blue:0 alpha:1]];
        [cell setSelectedBackgroundView:bgColorView];

        UIColor *backColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:1];
        cell.backgroundColor = backColor;
        UIColor *foreColor = [UIColor colorWithWhite:1 alpha:1];
        cell.textLabel.textColor = foreColor;

        cell.textLabel.text = @"row0";
    }
    else if ([indexPath row] == 1) 
    {
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        UIColor *backColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:1];
        cell.backgroundColor = backColor;
        UIColor *foreColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1];
        cell.textLabel.textColor = foreColor;

        cell.textLabel.text = @"row1";
    }
    else if ([indexPath row] == 2) 
    {
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        UIColor *backColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:1];
        cell.backgroundColor = backColor;
        UIColor *foreColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1];
        cell.textLabel.textColor = foreColor;

        cell.textLabel.text = @"row2";
    }
    return cell;
}

#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:[indexPath section]];
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
    [cell setSelectionStyle:UITableViewCellSelectionStyleBlue];

    [tableView selectRowAtIndexPath:path animated:YES scrollPosition:UITableViewScrollPositionNone];

}

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tvStat cellForRowAtIndexPath:indexPath];
    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}

#pragma mark Table view Gestures

-(IBAction)singleTapFrom:(UIGestureRecognizer *)tapRecog
{

    CGPoint tapLoc = [tapRecog locationInView:tvStat];
    NSIndexPath *tapPath = [tvStat indexPathForRowAtPoint:tapLoc];

    NSIndexPath *seleRow = [tvStat indexPathForSelectedRow];
    if([seleRow section] != [tapPath section])
        [self tableView:tvStat didDeselectRowAtIndexPath:seleRow];
    else if (seleRow == nil )
        {}
    else if([seleRow section] == [tapPath section] || [seleRow length] != 0)
        return;

    if(!tapPath)
        [self.view endEditing:YES];

    [self tableView:tvStat didSelectRowAtIndexPath:tapPath];
}

I use below approach and works fine for me,

class MyTableViewCell : UITableViewCell {

                var defaultStateColor:UIColor?
                var hitStateColor:UIColor?

                 override func awakeFromNib(){
                     super.awakeFromNib()
                     self.selectionStyle = .None
                 }

// if you are overriding init you should set selectionStyle = .None

                override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
                    if let hitColor = hitStateColor {
                        self.contentView.backgroundColor = hitColor
                    }
                }

                override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
                    if let defaultColor = defaultStateColor {
                        self.contentView.backgroundColor = defaultColor
                    }
                }

                override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
                    if let defaultColor = defaultStateColor {
                        self.contentView.backgroundColor = defaultColor
                    }
                }
            }

To override UITableViewCell's setSelected also works.

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Set background color
    let view = UIView()
    view.backgroundColor = UIColor.redColor()
    selectedBackgroundView = view
}

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 objective-c

Adding a UISegmentedControl to UITableView Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Warp \ bend effect on a UIView? Use NSInteger as array index Detect if the device is iPhone X Linker Command failed with exit code 1 (use -v to see invocation), Xcode 8, Swift 3 ITSAppUsesNonExemptEncryption export compliance while internal testing? How to enable back/left swipe gesture in UINavigationController after setting leftBarButtonItem? Change status bar text color to light in iOS 9 with Objective-C

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 selection-color

UITableView Cell selected Color?

Examples related to ui-select2

How to get Selected Text from select2 when using <input> How do I change selected value of select2 dropdown with JqGrid? Update select2 data without rebuilding the control set the width of select2 input (through Angular-ui directive) Is there a SELECT ... INTO OUTFILE equivalent in SQL Server Management Studio? Can I apply the required attribute to <select> fields in HTML5? jQuery UI tabs. How to select a tab based on its id not based on index How To Get Selected Value From UIPickerView UIButton: set image for selected-highlighted state How can I pass selected row to commandLink inside dataTable or ui:repeat?