UITableViewCell subview disappears when cell is se

2019-01-03 21:37发布

I'm implementing a color-chooser table view where the user can select amongst, say, 10 colors (depends on the product). The user can also select other options (like hard drive capacity, ...).

All color options are inside their own tableview section.

I want to display a little square on the left of the textLabel showing the actual color.

Right now I'm adding a simple square UIView, give it the correct background color, like this :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:RMProductAttributesCellID];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:RMProductAttributesCellID] autorelease];
        cell.indentationWidth = 44 - 8;

        UIView *colorThumb = [[[UIView alloc] initWithFrame:CGRectMake(8, 8, 28, 28)] autorelease];
        colorThumb.tag = RMProductAttributesCellColorThumbTag;
        colorThumb.hidden = YES;
        [cell.contentView addSubview:colorThumb];
    }

    RMProductAttribute *attr = (RMProductAttribute *)[_product.attributes objectAtIndex:indexPath.section];
    RMProductAttributeValue *value = (RMProductAttributeValue *)[attr.values objectAtIndex:indexPath.row];
    cell.textLabel.text = value.name;
    cell.textLabel.backgroundColor = [UIColor clearColor];

    UIView *colorThumb = [cell viewWithTag:RMProductAttributesCellColorThumbTag];
    colorThumb.hidden = !attr.isColor;
    cell.indentationLevel = (attr.isColor ? 1 : 0);

    if (attr.isColor) {
        colorThumb.layer.cornerRadius = 6.0;
        colorThumb.backgroundColor = value.color;
    }

    [self updateCell:cell atIndexPath:indexPath];

    return cell;
}

This displays fine without problems.

My only problem is that when I select a "color" row, during the fade-to-blue selection animation, my custom UIView (colorThumb) is hidden. It gets visible again just after the selection/deselection animation ended, but this produces an ugly artifact.

What should I do to correct this? Don't I insert the subview at the right place?

(There's nothing special in the didSelectRowAtIndexPath, I just change the cell's accessory to a checkbox or nothing, and deselect the current indexPath).

20条回答
Melony?
2楼-- · 2019-01-03 21:42

Another way to manage the problem is to fill the view with core-graphics gradient, like:

CAGradientLayer* gr = [CAGradientLayer layer];
gr.frame = mySubview.frame;
gr.colors = [NSArray arrayWithObjects:
                     (id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor]
                     ,(id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor]
                     , nil];

gr.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:1],nil];

[mySubview.layer insertSublayer:gr atIndex:0];
查看更多
劫难
3楼-- · 2019-01-03 21:44

Draw the view instead of setting background colour

import UIKit

class CustomView: UIView {

    var fillColor:UIColor!

    convenience init(fillColor:UIColor!) {
        self.init()
        self.fillColor = fillColor
    }

    override func drawRect(rect: CGRect) {
        if let fillColor = fillColor {
            let context = UIGraphicsGetCurrentContext()
            CGContextSetFillColorWithColor(context, fillColor.CGColor);
            CGContextFillRect (context, self.bounds);

        }
    }


}
查看更多
祖国的老花朵
4楼-- · 2019-01-03 21:45

For Swift 2.2 this works

cell.selectionStyle = UITableViewCellSelectionStyle.None

and reason is explained by @Andriy

It's because table view cell automatically changes background color of all views inside content view for highlighted state.

查看更多
神经病院院长
5楼-- · 2019-01-03 21:47

For may case, This is the Septs to avoid getting the gray color for all items in the cell (in case you are using custom table view cell):

  1. Set the selectionStyle to .none

查看更多
看我几分像从前
6楼-- · 2019-01-03 21:50

Place this code in your subclass of UITableViewCell

Swift 3 syntax

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

    if(selected) {
        lockerSmall.backgroundColor = UIColor.init(red: 233/255, green: 106/255, blue: 49/255, alpha: 1.0)
    }
}


override func setHighlighted(_ highlighted: Bool, animated: Bool) {
    super.setHighlighted(highlighted, animated: animated)

    if(highlighted) {
        lockerSmall.backgroundColor = UIColor.init(red: 233/255, green: 106/255, blue: 49/255, alpha: 1.0)
    }
}
查看更多
爷、活的狠高调
7楼-- · 2019-01-03 21:52

Don't forget to override setSelected as well as setHighlighted

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

    super.setHighlighted(highlighted, animated: animated)
    someView.backgroundColor = .myColour()
}

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

    super.setSelected(selected, animated: animated)
    someView.backgroundColor = .myColour()
}
查看更多
登录 后发表回答