35

I am developing an iPhone application, in my table view I wanted custom color for Cell Selection Style, I read the UITableViewCell Class Reference but there are only three constants defined for Selection style (Blue, Gray, None). I saw one application that used a different color than those defined in the reference.

How can we use a color other than those defined in the reference?

cottontail
  • 10,268
  • 18
  • 50
  • 51
Amit Vaghela
  • 2,970
  • 7
  • 33
  • 43
  • I would strongly recommend Matt Gallagher's approach over the one you accepted! Please consider giving it a look if you haven't already. – Adam Alexander Dec 10 '09 at 18:22
  • The answer's in this post are so messed up. Everyone please ignore the highest rated ones and go vote up the actual correct answers, which are at the bottom. – bentford Oct 25 '12 at 14:21

9 Answers9

64

The best way to set the selection is to set the selectedBackgroundView on the cell when you construct it.

i.e.

- (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.selectedBackgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SelectedCellBackground.png"]] autorelease];
    }

    // configure the cell
}

The image used should have a nice gradient (like the default selection). If you just want a flat color, you can use a UIView instead of a UIImageView and set the backgroundColor to the color you want.

This background is then automatically applied when the row is selected.

Matt Gallagher
  • 14,858
  • 2
  • 41
  • 43
  • 5
    What about for grouped style table views? I just used a rectangle image and it showed through the rounded curves of the tableview cells. +1 for a great answer. – fearmint Dec 04 '09 at 02:14
  • 3
    For grouped tableview cells you need 4 backgrounds -- top, bottom, middle and top&bottom and you need to apply them based on where the cell is in the group. – Matt Gallagher Dec 08 '09 at 00:17
  • Can you not do this without using images? – ingh.am Mar 11 '10 at 16:51
  • 1
    @james.ingham: you could use any kind of view for the selectedBackgroundView. You could use a regular UIView and set a flat backgroundColor. You could use a custom drawn UIView subclass. You cannot simply set a different tint; this can't be done. – Matt Gallagher Mar 14 '10 at 01:08
  • should do an autorelease on the selectedBackgroundView so it's not leaking. – stigi Apr 12 '10 at 10:06
  • 1
    This is only half correct. It will only show when the cell is selected, not while it's being pressed. See Willster's answer for solution. – bentford Oct 25 '12 at 14:23
24

Setting the selectedBackgroundView seems to have no effect when the cell.selectionStyle is set to UITableViewCellSelectionStyleNone. When I don't set the style is just uses the default gray.

Using the first suggestion that inserts the custom UIView into the cell does manipulate the cell but it doesn't show up when the cell is touched, only after the selected action is completed which is too late because I'm pushing to a new view. How do I get the selected view in the cell to display before the beginning of the selected operation?

eonil
  • 83,476
  • 81
  • 317
  • 516
Paul
  • 249
  • 2
  • 2
  • 4
    This is correct. I need to set selectionStyle to Blur or Gray. None will make it doesn't work. Anyway you can do this by overriding `-setHighlited:animated:` method of `UITableViewCell` class. – eonil Nov 30 '11 at 11:12
13

If you have subclassed a UITableViewCell, then you can customise the various elements of the cell by overriding the following:

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
    if(highlighted) {
        self.backgroundColor = [UIColor redColor];
    } else {
        self.backgroundColor = [UIColor clearColor];
    }

    [super setHighlighted:highlighted animated:animated];
}

EDIT for iOS7: as Sasho stated, you also need

cell.selectionStyle = UITableViewCellSelectionStyleNone
A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
Willster
  • 2,526
  • 1
  • 32
  • 32
  • In iOS 7 the above solution worked in combination with "cell. selectionStyle = UITableViewCellSelectionStyleNone". – Sasho Mar 09 '14 at 13:29
7

I tried some of the above, and I actually prefer to create my own subclass of UITableViewCell and then override the touchesBegan/touchesCancelled/touchesEnded methods. To do this, ignore all the selectedBackgroundView and highlightedColor properties on the cell, and instead just set these colors manually whenever one of the above methods are called. For example, if you want to set the cell to have a green background with red text, try this (within your custom cell subclass):

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //Set backgorund
    self.backgroundColor = [UIColor themeBlue];

    //Set text
    self.textLabel.textColor = [UIColor themeWhite];

    //Call super
    [super touchesBegan:touches withEvent:event];
}

Note that for this to work, you need to set:

self.selectionStyle = UITableViewCellSelectionStyleNone;

Otherwise, you'll first get the current selection style.

EDIT: I suggest using the touchesCancelled method to revert back to the original cell colors, but just ignore the touchesEnded method.

john.k.doe
  • 7,533
  • 2
  • 37
  • 64
Charles Marsh
  • 1,877
  • 16
  • 21
2

Override didSelectRowAtIndexPath: and draw a UIView of a color of your choosing and insert it behind the UILabel inside the cell. I would do it something like this:

UIView* selectedView; //inside your header

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

  UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
  selectedView = [[UIView alloc] initWithFrame:[cell frame]];
  selectedView.backgroundColor = [UIColor greenColor]; //whatever

  [cell insertSubview:selectedView atIndex:0]; //tweak this as necessary
  [selectedView release]; //clean up

}

You can choose to animate this view out when it gets deselected and will satisfy your requirements.

ingh.am
  • 25,981
  • 43
  • 130
  • 177
Jeffrey Forbes
  • 1,967
  • 1
  • 13
  • 10
  • 8
    This approach avoids Apple's built-in selectedBackgroundView on every UITableViewCell. If you use the selectedBackgroundView, your selection will animate in and out and will also unselected when instructed. – Matt Gallagher May 18 '09 at 11:51
  • 1
    It would be better to override `setSelected:highlighted:` in the cell and do the logic there if you are going to take this approach so it works in all view controllers. Like Matt said, using `selectedBackgroundView` is a much better approach. – Sam Soffes Aug 26 '10 at 22:22
1

Sublcass UITableViewCell and override setHighlighted:animated:

You can define a custom selection color color by setting the backgroundColor (see WIllster's answer):

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
    if(highlighted) {
        self.backgroundColor = [UIColor redColor];
    } else {
        self.backgroundColor = [UIColor clearColor];
    }

    [super setHighlighted:highlighted animated:animated];
}

You can define a custom background image by setting the backgroundView property:

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
    if( highlighted == YES )
        self.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"seasonal_list_event_bar_default.png"]];
    else
        self.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"seasonal_list_event_bar_active.png"]];


    [super setHighlighted:highlighted animated:animated];
}
bentford
  • 33,038
  • 7
  • 61
  • 57
0
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {  
// Set Highlighted Color  
if (highlighted) {  
self.backgroundColor = [UIColor colorWithRed:234.0f/255 green:202.0f/255 blue:255.0f/255 alpha:1.0f];
    } else {  
        self.backgroundColor = [UIColor clearColor];  
  }   
}
Darshan Kunjadiya
  • 3,323
  • 1
  • 29
  • 31
PK86
  • 1,218
  • 2
  • 14
  • 25
  • UITableViewCell has method to set highlighted state color Here, the code spinnet // animate between regular and highlighted state – PK86 Jul 04 '13 at 12:01
0
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
    // Add your Colour.
    SocialTableViewCell *cell = (SocialTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
    [self setCellColor:Ripple_Colour ForCell:cell];  //highlight colour
}

- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath {
    // Reset Colour.
    SocialTableViewCell *cell = (SocialTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
    [self setCellColor:Ripple_Colour ForCell:cell]; //normal color

}

- (void)setCellColor:(UIColor *)color ForCell:(UITableViewCell *)cell {
    cell.contentView.backgroundColor = color;
    cell.backgroundColor = color;
}
Ishwar Hingu
  • 562
  • 7
  • 14
0

To add a custom color use the below code. And to make it transparent use alpha: 0.0

cell.selectedBackgroundView = UIView(frame: CGRect.zero)
cell.selectedBackgroundView?.backgroundColor = UIColor(red:0.27, green:0.71, blue:0.73, alpha:1.0)

If you use custom color and want to give it rounded corner look use:

cell.layer.cornerRadius = 8

Also, use this for better animation and feel

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    tableView.deselectRow(at: indexPath, animated: true)
}
Prateekro
  • 566
  • 1
  • 6
  • 28