自定义UITableViewCell的选择样式?

87
当我点击UITableViewCell时,背景部分(即背景图像无法覆盖的区域)会变成蓝色。同时,当单击单元格时,所有的UILabel都会变成白色,这正是我想要的。
然而,我不想要的是单击单元格时出现蓝色背景,但如果我使用selectionstylenone,那么我就会失去单元格中UILabel的突出显示颜色。
所以,有没有什么办法只是消除单元格被单击时的蓝色背景,而保留UILabel的突出显示颜色呢?

https://dev59.com/q2Ml5IYBdhLWcg3w7qhq#25197607 - Waseem Shah
10个回答

179

您可以按照以下步骤完成此操作。将表格单元格的选择样式设置为UITableViewCellSelectionStyleNone,这将删除蓝色背景高亮显示。然后,为了使文本标签高亮显示按照您的意愿工作,不要使用默认的UITableViewCell 类,创建一个UITableViewCell 子类,并覆盖setHighlighted:animated的默认实现以根据突出显示状态设置标签颜色。

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

12
顺便提一下,请确保覆盖setHighlighted:animated:方法,并传入animated参数。仅覆盖一个参数的setHighlighted:方法是行不通的。 - Imre Kelényi
15
我们应该调用 [super setHighlighted:highlighted animated:animated]; 吗? - SoftDesigner
非常感谢!运行得很好!这使我能够控制在单元格中突出显示其他自定义视图,因为标准的突出显示做得很奇怪。 - imike
4
当你重写 setHighlightedsetSelected 方法时,这种方法存在一个问题。首先,当你选中一个单元格后,文本颜色会变为白色,然后你将该单元格滚出屏幕视野范围,再滚回来时,你会发现文本颜色变为黑色。 - ronan
2
@jonkroll 我理解了这个概念,但我的要求是当选择一个单元格时,该单元格的textLabel颜色应保持为selectedColor,目前只是在选择时更改textLabel的颜色,之后所选的textLabel仍然保持原来的颜色。 - Samarth Kejriwal
这个答案完全不正确。为什么会被接受?只有 setSelected 起作用。 - Gargo

77

如果在iOS7之前工作,请将单元格的选择样式设置为none。

cell.selectionStyle = UITableViewCellSelectionStyleNone;
< p >否则,将其保留为< code > UITableViewCellSelectionStyleDefault < /code > < p >然后: < /p >
UIView *selectedView = [[UIView alloc]init];
selectedView.backgroundColor = [UIColor redColor];
cell.selectedBackgroundView =  selectedView;

这段代码将正常工作


2
@iBradApps... 这里你没有创建任何自定义的 ui tableview cell 类... - Alfa
2
给这个点赞——这是唯一一个对我在iOS 7中更改选定单元格的非文本颜色有效的解决方案。 - Vern Jensen
1
selectionstyle 应该是 selectionStyle。 - braden
12
这个解决方案在iOS7上可行,但只有在我将selectionStyle设置为UITableViewCellStyleDefault后才有效。 - Jay Q.
1
这个方法是唯一与苹果的“开箱即用”单元格选择行为完全相同的方法。它应该被接受作为答案。 - mkll
显示剩余4条评论

16

在将选择样式设置为none之后,您可以使用以下委托方法:

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

在这里实现您的代码,像这样

-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    CustomCell *cell = (CustomCell *)[tableView cellForRowAtIndexPath:indexPath];
    [cell.lbls setTextColor:[UIColor whiteColor]];
    return indexPath;
}

1
非常棒且简洁的解决方案!你只需要实现willDeselectRowAtIndexPath调用,它就像魔法一样工作! - Matej Balantič
1
这里可能存在一个缺点,即该方法直到您的手指离开所选单元格后才被调用;而其他一些方法则在您触摸单元格时立即生效。 - arlomedia

16
为了实现这个功能,你需要将选择样式设置为UITableViewCellSelectionStyleNone,然后重写setSelected:animated:方法以达到所需的效果。这样做与iOS自动选择机制产生的蓝色(或灰色)选择相同。
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    if (selected) {
        self.textLabel.textColor = [UIColor whiteColor];
    } else {
        self.textLabel.textColor = [UIColor blackColor];
    }
}

你也可以以另一种方式自定义它,例如通过更改UITableViewCell的背景等。


14
在`cellForRowAtIndexPath`方法中使用以下代码:
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

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

希望这对你有用。

享受编码 :)


这个答案需要置顶。 :) - Chintan Patel
2
这样行不通。如果你想要设置 [cell.textLabel setHighlightedTextColor:[UIColor blueColor]]; 那么单元格的selectionStyle不能是NONE。 - Femina

6
在您的UITableViewCell子类中,重写以下函数。
override func setHighlighted(highlighted: Bool, animated: Bool) { }
override func setSelected(selected: Bool, animated: Bool) { }

谢谢您;这是唯一一个在更改背景颜色时不会选择整行从屏幕左边到右边的代码。 - Hedylove
我只覆盖了setSelected方法,这就是为什么有时候单元格仍然会闪烁的原因。 - Zonily Jame

3
为了匹配标准的选择样式行为,您需要覆盖setHighlighted:animated:setSelected:animated:两个方法。您可能需要将该代码移动到共享方法中,以避免重复代码。
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()
    }
}

1
在您的自定义单元格中,覆盖默认的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];
    }
}

请确保选择样式未设置为“无”。

0

我能让它工作的唯一方法是:

- (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;
}

0

你也可以使用contentView.alpha。这里是一个例子。

首先,为你的单元格设置选择样式:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

接下来,在自定义单元格类中,使用动画示例覆盖此方法:
  - (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;
        }];
    }
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接