选择时如何更改 UITableViewCell 的颜色?

Posted

技术标签:

【中文标题】选择时如何更改 UITableViewCell 的颜色?【英文标题】:How to change color of UITableViewCell when selecting? 【发布时间】:2013-04-22 08:28:04 【问题描述】:

我有一个这样的菜单:

每个单元格的正常(未选中)状态是一个图像,选中状态也是一个图像(看起来像默认的蓝色)。但是,我想再添加第三张图片,这样当用户选择一个单元格时,它会在变为蓝色(选中)之前短暂地变为第三种颜色。

这是我的代码:

(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    [tableView setBackgroundColor:[UIColor clearColor]];

    NSString *cellIdentifier = @"MenuItemCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle  reuseIdentifier:cellIdentifier];
    

    UIImage *cellBackgroundNormal = [UIImage imageNamed:@"cell_menu_normal"];
    UIImage *cellBackgroundSelected = [UIImage imageNamed:@"cell_menu_selected"];
    UIImageView *cellBackgroundView = [[UIImageView alloc] initWithImage:cellBackgroundNormal];
    UIImageView *cellBackgroundSelectedView = [[UIImageView alloc] initWithImage:cellBackgroundSelected];
    cell.backgroundView = cellBackgroundView;
    cell.selectedBackgroundView = cellBackgroundSelectedView;

    [cell.textLabel setBackgroundColor:[UIColor clearColor]];
    [cell.textLabel setTextColor:[UIColor whiteColor]];
    [cell.textLabel setFont:[UIFont boldSystemFontOfSize:17.0]];
    cell.textLabel.text = [self.menuItems objectAtIndex:indexPath.row];

    return cell;
 

如您所见,我目前只有两种状态。我不知道如何为第三张图片引入某种cell.hoveredBackgroundView。如果有人可以帮助我实现这一点,我将不胜感激。

【问题讨论】:

【参考方案1】:

在 Swift 5 中:

在您的自定义单元格下,实现此方法。 highlighted 表示您按下它但尚未抬起手指。可以对比苹果音乐库页面列表,也是一样的行为。

    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)
        
        if selected 
            cellLabel.textColor = .white
            cellImageView.tintColor = .white
         else 
            cellLabel.textColor = .black
            cellImageView.tintColor = .systemPink
        
    

    override func setHighlighted(_ highlighted: Bool, animated: Bool) 
        super.setHighlighted(highlighted, animated: animated)
        
        if highlighted 
            cellLabel.textColor = .white
            cellImageView.tintColor = .white
         else 
            cellLabel.textColor = .black
            cellImageView.tintColor = .systemPink
        
    

【讨论】:

【参考方案2】:

斯威夫特:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
    tableView.deselectRowAtIndexPath(indexPath, animated: true)


override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) 
    let selectionColor = UIView() as UIView
    selectionColor.layer.borderWidth = 1
    selectionColor.layer.borderColor = UIColor.blueColor().CGColor
    selectionColor.backgroundColor = UIColor.blueColor()
    cell.selectedBackgroundView = selectionColor

斯威夫特 4:

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

    tableView.deselectRow(at: indexPath, animated: true)


override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)

    let selectionColor = UIView() as UIView
    selectionColor.layer.borderWidth = 1
    selectionColor.layer.borderColor = UIColor.blue.cgColor
    selectionColor.backgroundColor = UIColor.blue
    cell.selectedBackgroundView = selectionColor

【讨论】:

【参考方案3】:

使用 Swift 的 iOS 8.0(及更高版本)

斯威夫特 2

override func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool 
    return true


override func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath) 
    var cell = tableView.cellForRowAtIndexPath(indexPath)
    cell?.contentView.backgroundColor = UIColor.orangeColor()
    cell?.backgroundColor = UIColor.orangeColor()


override func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath) 
    var cell = tableView.cellForRowAtIndexPath(indexPath)
    cell?.contentView.backgroundColor = UIColor.blackColor()
    cell?.backgroundColor = UIColor.blackColor()

斯威夫特 3

override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool 
    return true


override func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) 
    let cell = tableView.cellForRow(at: indexPath)
    cell?.contentView.backgroundColor = UIColor.orange
    cell?.backgroundColor = UIColor.orange


override func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath) 
    let cell = tableView.cellForRow(at: indexPath)
    cell?.contentView.backgroundColor = UIColor.black
    cell?.backgroundColor = UIColor.black

【讨论】:

【参考方案4】:

我最终得到以下代码。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

  //  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[cellIdArray objectAtIndex:indexPath.row] forIndexPath:indexPath];

    // Configure the cell...
    cell.backgroundView =
    [[UIImageView alloc] init] ;
    cell.selectedBackgroundView =[[UIImageView alloc] init];

    UIImage *rowBackground;
    UIImage *selectionBackground;


    rowBackground = [UIImage imageNamed:@"cellBackgroundDarkGrey.png"];
    selectionBackground = [UIImage imageNamed:@"selectedMenu.png"];

    ((UIImageView *)cell.backgroundView).image = rowBackground;
    ((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;



    return cell;

【讨论】:

【参考方案5】:

自定义 UITableViewCell Swift 3.0

override func awakeFromNib() 
        super.awakeFromNib()

        let selectedBackgroundView = UIView();
        selectedBackgroundView.backgroundColor = UIColor.lightGray;
        self.selectedBackgroundView = selectedBackgroundView;
    

【讨论】:

【参考方案6】:

对于 Swift 3

self.tableView.reloadData()
let selectedCell = tableView.cellForRow(at: indexPath)
selectedCell?.contentView.backgroundColor = UIColor.red

【讨论】:

【参考方案7】:

在 cellForRowAtIndexPath 方法中添加以下代码

var cell=tableView.dequeueReusableCellWithIdentifier("cell")!
var viewBG=UIView(frame: CGRectMake(0,0,self.view.frame.size.width,50))
viewBG.backgroundColor=UIColor(colorLiteralRed: 71.0/255.0, green: 121.0/255.0, blue: 172.0/255.0, alpha: 1)
cell.selectedBackgroundView=viewBG

【讨论】:

【参考方案8】:

使用 Objective C,更改选定单元格的背景颜色而不是默认值。无需创建自定义单元格。

如果您只想更改单元格的选定颜色,您可以执行此操作,请注意,要使其正常工作,在情节提要(或 XIB 文件)中,您必须选择“无”以外的选定背景颜色。只需在 UITableView Delegate 方法中添加以下代码:tableView cellForRowAtIndexPath:

UIView *bgColor = [[UIView alloc] init];

bgColor.backgroundColor = [UIColor yellowColor];

[cell setSelectedBackgroundView:bgColor];

【讨论】:

【参考方案9】:

根据 Milan Cermak 的回答,您可以使用UIAppearance

Swift 1.1 / 2.0:

let selectionView = UIView()
selectionView.backgroundColor = UIColor.redColor()
UITableViewCell.appearance().selectedBackgroundView = selectionView

【讨论】:

【参考方案10】:

你也可以像这样使用 UIAppearance:

UIView *selectionView = [UIView new];
selectionView.backgroundColor = [UIColor redColor];
[[UITableViewCell appearance] setSelectedBackgroundView:selectionView];

这将适用于 UITableViewCell 的所有实例或其任何您可能拥有的子类。只需确保单元格的 selectionStyle 属性设置为 UITableViewCellSelectionStyleNone

【讨论】:

谢谢!这是,放下,最优雅的答案。接受的答案看起来像过去的代码。 这是 Swift 中的相同代码: d.pr/n/14HUv 然而,在这个解决方案中,多重选择的行为非常奇怪。 (只能高亮一行) 这会在导航中弹出回到前一个表格视图控制器时破坏单元格的取消选择动画:取消选择会立即生效,并且无法判断选择了哪一行。【参考方案11】:

比接受的答案更容易:

在你的 UITableViewCell 子类中:

awakeFromNibinit

self.selectionStyle = UITableViewCellSelectionStyleNone;

然后:

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated

    [super setHighlighted:highlighted animated:animated];

    if (highlighted) 
        self.backgroundColor = [UIColor yourHighlightColor];
    
    else 
        self.backgroundColor = [UIColor yourNormalColor];
    

【讨论】:

【参考方案12】:

iOS 6.0 及更高版本

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath 
return YES;


- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath 
  // Add your Colour.
    CustomCell *cell = (CustomCell *)[tableView cellForRowAtIndexPath:indexPath];
    [self setCellColor:[UIColor whiteColor] ForCell:cell];  //highlight colour


- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath 
  // Reset Colour.
    CustomCell *cell = (CustomCell *)[tableView cellForRowAtIndexPath:indexPath];
    [self setCellColor:[UIColor colorWithWhite:0.961 alpha:1.000] ForCell:cell]; //normal color



- (void)setCellColor:(UIColor *)color ForCell:(UITableViewCell *)cell 
    cell.contentView.backgroundColor = color;
    cell.backgroundColor = color;

自定义 UITableViewCell

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

    UIView * selectedBackgroundView = [[UIView alloc] init];
    [selectedBackgroundView setBackgroundColor:[UIColor colorFromHexString:@"5E6073"]]; // set color here
    [self setSelectedBackgroundView:selectedBackgroundView];

【讨论】:

谢谢,就是这样!我还必须实现didUnhighlightRowAtIndexPath 来处理取消选择行时的图像更改。 您能否改进代码以显示如何更改单元格的颜色? :) @Lucien 我已经更新了代码。看看吧 我尝试了许多其他解决方案,这是唯一一个有效的解决方案。不错! 我不同意这个解决方案。您不会将 selectedBackgroundView 创建为 setSelected 方法的一部分。您在创建自定义 UITableViewCell 本身时执行此操作。【参考方案13】:

在自定义单元格中试试这个-

- (void)awakeFromNib

    UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:self.bounds];
    selectedBackgroundView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    selectedBackgroundView.backgroundColor = [UIColor colorWithRed:246.0/255.0 green:95.0/255.0 blue:22.0/255.0 alpha:1.0];
    self.selectedBackgroundView = selectedBackgroundView;

【讨论】:

【参考方案14】:

您可以创建一个自定义 UITableViewCell,在其中添加一个具有单元格大小的 UIButton。然后您可以轻松地为 UIButton 的 TouchDown(悬停)和 TouchUpInside 事件自定义方法,并设置背景。

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) 
        cellButton = [[UIButton alloc] initWithFrame:self.contentView.frame];
        UIImage *cellBackgroundNormal = [UIImage imageNamed:@"cell_menu_normal"];
        UIImageView *cellBackgroundView = [[UIImageView alloc] initWithImage:cellBackgroundNormal];
        self.backgroundView = cellBackgroundView;

        [cellButton addTarget:self action:@selector(hoverCell) forControlEvents:UIControlEventTouchDown];
        [cellButton addTarget:self action:@selector(tapCell) forControlEvents:UIControlEventTouchUpInside];
    
    return self;


- (void)hoverCell

    UIImage *cellBackgroundHover = [UIImage imageNamed:@"cell_menu_third_image"];
    UIImageView *cellBackgroundHoverView = [[UIImageView alloc] initWithImage:cellBackgroundHover];
    self.backgroundView = cellBackgroundHoverView;


- (void)tapCell

    UIImage *cellBackgroundSelected = [UIImage imageNamed:@"cell_menu_selected"];
    UIImageView *cellBackgroundSelectedView = [[UIImageView alloc] initWithImage:cellBackgroundSelected];
    self.backgroundView = cellBackgroundSelectedView;

【讨论】:

【参考方案15】:

您可以引入一个计时器来设置 2 种不同背景颜色之间的所需时间(如果我理解的话,例如 1/2 秒)?但你可能已经想到了:/

【讨论】:

我认为这行不通,因为只要用户将手指放在所选菜单项上并且仅在发布时将其更改为蓝色,我就希望它处于中间状态.例如,它就像一个按钮,具有自己的突出显示状态。 这些看起来很老套,并不完全可靠

以上是关于选择时如何更改 UITableViewCell 的颜色?的主要内容,如果未能解决你的问题,请参考以下文章

选择时更改 UITableViewCell 的 alpha 啥都不做

UITableViewCell 的选择颜色

在选择时更改 UITableViewCell 的边框颜色

iPhone UITableViewCell selectionStyle 编辑时?

如何在点击时更改 UITableViewCell 的部分位置

使用 UIButton 自定义 UITableViewCell:无法更改 UIImage