87

When I click on my UITableViewCell, the background part (the areas that my background image doesn't cover) turns blue when I click on the cell. Also, all of the UILabels on the cell turn to white when it is clicked which is what I want.

However what I do not want is the blue background when I click it but if I do selectionstylenone, then I lose the highlighted colours for the UILabels in the cell.

So is there any way to just get rid of the blue background when the cell is clicked but to keep the highlighted colors of the UILabels?

Ricardo Sanchez-Saez
  • 9,466
  • 8
  • 53
  • 92
SimplyKiwi
  • 12,376
  • 22
  • 105
  • 191

10 Answers10

179

You can do this as follows. Set your table cell's selection style to UITableViewCellSelectionStyleNone. This will remove the blue background highlighting. Then, to make the text label highlighting work the way you want, instead of using the default UITableViewCell class, create a subclass of UITableViewCell and override the default implementation of setHighlighted:animated with your own implementation that sets the label colors to however you want depending on the highlighted state.

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
    if (highlighted) {
        self.textLabel.textColor = [UIColor whiteColor];
    } else {
        self.textLabel.textColor = [UIColor blackColor];
    }
}
jonkroll
  • 15,682
  • 4
  • 50
  • 43
  • 12
    As a side note, make sure you override `setHighlighted:animated:`, which takes the `animated` parameter. Overriding the one parameter `setHighlighted:` method will not work. – Imre Kelényi Dec 03 '13 at 16:22
  • 15
    Should we call ```[super setHighlighted:highlighted animated:animated];``` ? – SoftDesigner Oct 22 '14 at 12:13
  • Thanks a lot! Works like a charm! And this give me control on highlighting another custom views in cell if I want, because standard highlighting doing it strange. – imike Dec 23 '14 at 10:33
  • 4
    But this method has one problem when you override `setHighlighted` and `setSelected`. First you select a cell, ok the textColor change to white, then you scroll that cell out of your screen visual part, then scroll back, see, the textColor go black – ronan May 16 '16 at 02:49
  • 2
    @jonkroll I understood the concept, but my requirement is that when a cell is being selected then the color of the textLabel of that cell should remain as the selectedColor, right now it is just changing the color of the textLabel while selection, after that the selected textLabel remains in the original color – Samarth Kejriwal Dec 11 '17 at 05:34
  • This answer is totally incorrect. Why is it accepted? Only `setSelected` works. – Gargo May 15 '23 at 07:40
77

If working before iOS7, make your cell selection style none

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Else, leave it by UITableViewCellSelectionStyleDefault

Then:

UIView *selectedView = [[UIView alloc]init];
selectedView.backgroundColor = [UIColor redColor];
cell.selectedBackgroundView =  selectedView;

This code will work properly

Tulleb
  • 8,919
  • 8
  • 27
  • 55
Alfa
  • 975
  • 7
  • 15
  • Any explanation for why this answer is better than the accepted one? – SimplyKiwi Aug 15 '13 at 04:15
  • 2
    @iBradApps... here you are not creating any custom class... of ui tableview cell – Alfa Aug 16 '13 at 07:13
  • @Alfa the accepted answer is more precise, because it has control over two states: highlighted and not. In iOS 7 changes cell's `contentView.backgroundColor` back to white and then to the custom color. – pbibergal Sep 25 '13 at 07:03
  • 2
    Giving this an upvote -- it's the only solution that worked for me for changing the non-text color of a selected cell in iOS 7. – Vern Jensen Oct 08 '13 at 20:25
  • 1
    selectionstyle should be selectionStyle – braden Nov 13 '13 at 00:52
  • 12
    This solution worked on iOS7 but only after I set selectionStyle to UITableViewCellStyleDefault. – Jay Q. Jun 11 '14 at 07:28
  • 1
    This method is the only method that absolutely identically to Apple's "out of box" cell selection behavior. It should be accepted answer. – mkll Jun 30 '14 at 02:16
  • The problem with this is it only changes the background. Normally you would also want to change foreground colors as well. – hasen Feb 08 '18 at 05:47
  • I like the solution – Reimond Hill Jun 25 '18 at 09:03
16

You can use the following delegate methods after you set the selection style to none:

-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath

Implement your code here, like this

-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    CustomCell *cell = (CustomCell *)[tableView cellForRowAtIndexPath:indexPath];
    [cell.lbls setTextColor:[UIColor whiteColor]];
    return indexPath;
}
Scar
  • 3,460
  • 3
  • 26
  • 51
  • 1
    Great & clean solution! You only have to implement the willDeselectRowAtIndexPath call and it works like magic! – Matej Balantič Jan 05 '14 at 13:47
  • 1
    A possible downside here is that this method is not called until your finger leaves the selected cell; some other approaches take effect as soon as you touch the cell. – arlomedia Mar 06 '14 at 01:31
16

To get this work you have to set the selection style to UITableViewCellSelectionStyleNone and then you should override the method setSelected:animated: to get the result you want. It does the same thing the automated selection mechanism of iOS does when you see the blue (or gray) selection.

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    if (selected) {
        self.textLabel.textColor = [UIColor whiteColor];
    } else {
        self.textLabel.textColor = [UIColor blackColor];
    }
}

You can also customize this in another way, e.g. by changing the UITableViewCell background, etc.

who9vy
  • 1,091
  • 9
  • 19
14

In cellForRowAtIndexPath use this code:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

[cell.myLabel setHighlightedTextColor: [UIColor whiteColor]]; // for all your labels

Hope this will work for you.

Enjoy Coding :)

Mrunal
  • 13,982
  • 6
  • 52
  • 96
6

Overriding the following functions in your subclass of UITableViewCell.

override func setHighlighted(highlighted: Bool, animated: Bool) { }
override func setSelected(selected: Bool, animated: Bool) { }
superarts.org
  • 7,009
  • 1
  • 58
  • 44
  • Thank you; this was the only one that doesn't cause the entire row from left edge of the screen to right to be selected when changing the background color. – Hedylove Mar 11 '18 at 05:24
  • I was only overriding setSelected which is why for some reason the cell was still flashing sometimes. – Zonily Jame Sep 19 '18 at 09:07
3

In order to match the standard selection style behavior, you'll want to override both setHighlighted:animated: and setSelected:animated:. You'll probably want to move that code into a shared method in order to avoid duplicate code.

override func setHighlighted(highlighted: Bool, animated: Bool) {

    setAsSelectedOrHighlighted(highlighted, animated: animated)
    super.setHighlighted(highlighted, animated: animated)
}

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

    setAsSelectedOrHighlighted(selected, animated: animated)
    super.setSelected(selected, animated: animated)
}

func setAsSelectedOrHighlighted(selectedOrHighlighted: Bool, animated: Bool) {

    let action = {
        // Set animatable properties
    }

    if animated {
        UIView.animateWithDuration(1.0, delay: 0, options: .CurveEaseInOut, animations: action, completion: nil)
    }
    else {
        action()
    }
}
Logan Gauthier
  • 393
  • 2
  • 6
1

In your custom cell, override the default implementation of awakeFromNib & setSelected:

- (void)awakeFromNib {
    // Initialization code
    UIImageView * imageView = [[UIImageView alloc] initWithFrame:self.bounds];
    imageView.image = [UIImage imageNamed:@"cell_selected_img"];
    self.selectedBackgroundView = imageView;
}

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

    // Configure the view for the selected state
    if (selected) {
        self.lblCustomText.textColor = [UIColor whiteColor];
    } else {
        self.lblCustomText.textColor = [UIColor blackColor];
    }
}

Also make sure that the selection style is NOT set to None.

zeeawan
  • 6,667
  • 2
  • 50
  • 56
0

The only way I could get it working was by:

- (void)awakeFromNib {
    UIView *bgColorView = [[UIView alloc] init];
    bgColorView.backgroundColor = [UIColor colorWithRed:(55.0/255.0) green:(163.0/255.0) blue:(237.0/255.0) alpha:1.0];
    bgColorView.layer.masksToBounds = YES;
    self.selectedBackgroundView = bgColorView;
}
Rudolf Real
  • 1,948
  • 23
  • 27
0

Also you can use contentView.alpha. Here is the example.

First, set selection style for your cell:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Next, in custom cell class override this method with animation example:

  - (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
    [super setHighlighted:highlighted animated:animated];

    if (highlighted) {
        [UIView animateWithDuration:0.15f animations:^{
            self.contentView.alpha = 0.5f;
        }];
    } else {
        [UIView animateWithDuration:0.35f animations:^{
            self.contentView.alpha = 1.f;
        }];
    }
  }
Alex Kolovatov
  • 859
  • 7
  • 12