Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The selectedBackgroundView modifies the contentView subviews

I'm using a custom backgroundView and selectedBackgroundView for a UITableViewCell subclass. These cells are in a grouped table, so I'm setting the background and selected background as UIImageViews based on the cell's row in cellForRowAtIndexPath:.

The problem I'm having is that when the cell is selected, its selectedBackgroundView modifies the contents of the contentView. For example, after selecting and/or highlighting a cell, the UILabel in the contentView has its backgroundColor changes and the UIView being used as a cell separator is not visible.

Before selection: Before selection/highlight After selection: After selection/highlight

I don't see this behavior documented anywhere. Is there something I need to do to prevent this? Is there a different approach to showing cell selection/highlighting that I should take to prevent this?

  • Note: Since it's a grouped table view, I set a different backgroundViews and selectedBackgroundViews with UIImageViews to account for the rounded corners on the top and bottom cells in the section in cellForRowAtIndexPath:, but I have the same problem when using the default UITableViewSelectionStyleBlue.

Edit 1:

Per an0's answer, I overrode setHighlighted:animated:. I'm not sure how reliable the implementation is, but this approach worked to maintain the highlighted and backgroundColor properties of the subviews:

NSArray *recursiveAllSubviews = [self recursiveValueForKey:@"subviews"]; // Uses MTRecursiveKVC Cocoapod
NSArray *backgroundColors = [recursiveAllSubviews valueForKey:@"backgroundColor"];
[super setHighlighted:highlighted animated:animated];
if (highlighted) {
    [recursiveAllSubviews enumerateObjectsUsingBlock:^(UIView *view, NSUInteger index, BOOL *stop){
        if ([view respondsToSelector:@selector(setHighlighted:)]) {
            [view setValue:[NSNumber numberWithBool:NO] forKey:@"highlighted"];
        }
        id possiblyNull = [backgroundColors objectAtIndex:index];
        if (possiblyNull != [NSNull null]) {
            view.backgroundColor = possiblyNull;
        }
    }];
}
like image 270
MaxGabriel Avatar asked Jan 22 '13 21:01

MaxGabriel


3 Answers

UITableViewCell does two things automatically when highlighted/selected:

  1. Set all its subviews' backgroundColor to clear color(transparent).
  2. Highlight all subviews that can be highlighted, for example, UIImageView.

To prevent the first problem, you have to override these two methods in your UITableViewCell subclass:

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
    [super setHighlighted:highlighted animated:animated];
    if (highlighted) {
        // Recover backgroundColor of subviews.
    }
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    if (selected) {
        // Recover backgroundColor of subviews.
    }
}
like image 169
an0 Avatar answered Nov 20 '22 16:11

an0


set cell.selectionStyle = UITableViewCellSelectionStyleNone and override

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
  if(highlighted) {
    self.contentView.backgroundColor = colorYouWantWhenHighlighted;
  } else {
    self.contentView.backgroundColor = colorYouWantWhenUnhighlighted;
  }
}
like image 34
nyus2006 Avatar answered Nov 20 '22 16:11

nyus2006


In my case, I had two buttons in my UITableViewCell whose background colors were being cleared. These buttons were of type GrayButton, a custom class I wrote that derives UIButton. Rather than override UITableViewCell methods, I instead overrode GrayButton's setBackgroundColor: method:

- (void)setBackgroundColor:(UIColor *)backgroundColor
{
    if (backgroundColor != [UIColor clearColor]) {
        [super setBackgroundColor:backgroundColor];
    }
}
like image 39
NathanAldenSr Avatar answered Nov 20 '22 17:11

NathanAldenSr