【问题标题】:Changing background color of selected cell?更改所选单元格的背景颜色?
【发布时间】:2011-01-25 23:12:52
【问题描述】:

有谁知道如何使用 UITableViewCell 为每个选定的单元格更改单元格的背景颜色?我在 TableView 的代码中创建了这个 UITableViewCell。

【问题讨论】:

    标签: iphone uitableview colors background tableview


    【解决方案1】:

    更改属性 selectedBackgroundView 是正确且最简单的方法。我使用以下代码更改选择颜色:

    // set selection color
    UIView *myBackView = [[UIView alloc] initWithFrame:cell.frame];
    myBackView.backgroundColor = [UIColor colorWithRed:1 green:1 blue:0.75 alpha:1];
    cell.selectedBackgroundView = myBackView;
    [myBackView release];
    

    【讨论】:

    • 是的,但是在选择部分中的第一个或最后一个单元格时,这在 UITableViewStyleGrouped 中看起来不太好。
    • @manicaesar 但它仍然适用于 iOS7+ :) UITableViewStyleGrouped 模式下不再有圆角
    【解决方案2】:

    我终于设法让它在样式设置为 Grouped 的表格视图中工作。

    首先将所有单元格的selectionStyle属性设置为UITableViewCellSelectionStyleNone

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    

    然后在您的表视图委托中实现以下内容:

    static NSColor *SelectedCellBGColor = ...;
    static NSColor *NotSelectedCellBGColor = ...;
    
    - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSIndexPath *currentSelectedIndexPath = [tableView indexPathForSelectedRow];
        if (currentSelectedIndexPath != nil)
        {
            [[tableView cellForRowAtIndexPath:currentSelectedIndexPath] setBackgroundColor:NotSelectedCellBGColor];
        }
    
        return indexPath;
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [[tableView cellForRowAtIndexPath:indexPath] setBackgroundColor:SelectedCellBGColor];
    }
    
    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (cell.isSelected == YES)
        {
            [cell setBackgroundColor:SelectedCellBGColor];
        }
        else
        {
            [cell setBackgroundColor:NotSelectedCellBGColor];
        }
    }
    

    【讨论】:

    • 这是最好的答案!
    • 很抱歉通知您,但是您的解决方案不起作用,xcode 5,iOS7
    • @SAFAD 刚刚在 iOS7/Xcode 5 下为一个普通的 UITableView 实现了这个。我不得不在cellForRowAtIndexPath: 中使用额外的逻辑来处理在单元格被滚动回视图后正确显示选定的单元格,所以这可能是你的问题。
    • 你不需要重写 didDeselectRowAtIndexPath 吗?
    • @EvanR 你添加了什么额外的逻辑?
    【解决方案3】:

    SWIFT 4、XCODE 9、IOS 11

    经过一些测试后,当表格视图选择设置为“多选”时,在取消选择或第二次点击单元格时移除背景颜色。当表格视图样式设置为“分组”时也可以使用。

    extension ViewController: UITableViewDelegate {
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            if let cell = tableView.cellForRow(at: indexPath) {
                cell.contentView.backgroundColor = UIColor.darkGray
            }
        }
    }
    

    注意:为了使这个工作如下所示,您的单元格的选择属性可以设置为任何值,但无。

    不同选项的外观

    样式:普通,选择:单选

    样式:普通,选择:多选

    样式:分组,选择:多选

    奖金 - 动画

    要获得更平滑的颜色过渡,请尝试一些动画:

    extension ViewController: UITableViewDelegate {
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            if let cell = tableView.cellForRow(at: indexPath) {
                UIView.animate(withDuration: 0.3, animations: {
                    cell.contentView.backgroundColor = UIColor.darkGray
                })
            }
        }
    }
    

    奖金 - 文字和图像更改

    You may notice the icon and text color also changing when cell is selected.这会在您设置 UIImage 和 UILabel Highlighted 属性时自动发生

    UIImage

    1. 提供两张彩色图片:

    1. 设置高亮图像属性:

    UILabel

    只需为 Highlighted 属性提供一种颜色:

    【讨论】:

    • 感谢奖金 - 文本和图像更改。第一次知道标签高亮的用法
    • 我有简单的样式,我有单选,但我有自定义单元格,行为就像我点击项目时一样,它会变成彩色背景,但是当我点击另一个单元格时,第一个项目的背景永远不会回去。为什么会这样??
    • @MarkMoeykens 当我用每个情节提要设置实现上述内容时,单元格在我第二次按下后没有“取消选择”......即使我有一段代码明确将其颜色设置为白色
    • 我正在寻找 OSX 解决方案。我可以更改单元格颜色,但无法隐藏/取消隐藏单元格内的按钮。有什么帮助吗?
    【解决方案4】:
    // animate between regular and selected state
    - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    
        [super setSelected:selected animated:animated];
    
        if (selected) {
            self.backgroundColor = [UIColor colorWithRed:234.0f/255 green:202.0f/255 blue:255.0f/255 alpha:1.0f];
        }
        else {
            self.backgroundColor = [UIColor clearColor];
        }
    }
    

    【讨论】:

    • 我尝试这样做,但将self.backgroundView 设置为任一场景的交替图像 - 无法使其正常工作。我什至尝试将self.selectedBackgroundView 放入if (selected)nil 先将每个视图输出。试图弄清楚我在这里缺少什么!最终不得不通过更改if 语句中的self.backgroundView 并在else 语句中调用self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:]] 来做到这一点。
    【解决方案5】:
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
         UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
         cell.contentView.backgroundColor = [UIColor yellowColor];
    
    }
    

    【讨论】:

    • 这样做的问题是之前选择的其他行仍然具有新的背景颜色。
    • @vnchopra,我认为这可能自 2013 年以来发生了变化,但我刚刚尝试过,当您选择另一个单元格时它确实会被删除。 (Xcode 9、iOS 11、Swift 4)
    【解决方案6】:

    我创建了 UIView 并设置了单元格 selectedBackgroundView 的属性:

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

    【讨论】:

    • 对于适用于 iOS 7(及更高版本?)的UIAppearance(正确)使用其默认selectedBackgroundView 设置颜色的解决方案,请查看我的answer 到类似问题.
    【解决方案7】:

    如果您在谈论选定的单元格,则属性为-selectedBackgroundView。这将在用户选择您的单元格时显示。

    【讨论】:

      【解决方案8】:

      我在以下方面很幸运:

      - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
      {
          bool isSelected = // enter your own code here
          if (isSelected)
          {
              [cell setBackgroundColor:[UIColor colorWithRed:1 green:1 blue:0.75 alpha:1]];
              [cell setAccessibilityTraits:UIAccessibilityTraitSelected];
          }
          else
          {
              [cell setBackgroundColor:[UIColor clearColor]];
              [cell setAccessibilityTraits:0];
          }
      }
      

      【讨论】:

        【解决方案9】:

        我有一个高度定制的 UITableViewCell。所以我实现了我自己的单元格选择。

        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        

        我在单元格的类中创建了一个方法:

        - (void)highlightCell:(BOOL)highlight
        {
            if (highlight) {
                self.contentView.backgroundColor = RGB(0x355881);
                _bodyLabel.textColor = RGB(0xffffff);
                _fromLabel.textColor = RGB(0xffffff);
                _subjectLabel.textColor = RGB(0xffffff);
                _dateLabel.textColor = RGB(0xffffff);
            }
            else {
                self.contentView.backgroundColor = RGB(0xf7f7f7);;
                _bodyLabel.textColor = RGB(0xaaaaaa);
                _fromLabel.textColor = [UIColor blackColor];
                _subjectLabel.textColor = [UIColor blackColor];
                _dateLabel.textColor = RGB(0x496487);
            }
        }
        

        在 ViewWillAppear 的 UITableViewController 类中添加了这个:

        NSIndexPath *tableSelection = [self.tableView indexPathForSelectedRow];
        SideSwipeTableViewCell *cell = (SideSwipeTableViewCell*)[self.tableView cellForRowAtIndexPath:tableSelection];
        [cell highlightCell:NO];
        

        在 didSelectRow 中添加了这个:

        SideSwipeTableViewCell *cell = (SideSwipeTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];
        [cell highlightCell:YES];
        

        【讨论】:

          【解决方案10】:

          我能够通过创建UITableViewCell 的子类并实现 setSelected:animated: 方法来解决这个问题

          - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
              [super setSelected:selected animated:animated];
          
              // Configure the view for the selected state
              if(selected) {
                  [self setSelectionStyle:UITableViewCellSelectionStyleNone];
                  [self setBackgroundColor:[UIColor greenColor]];
              } else {
                  [self setBackgroundColor:[UIColor whiteColor]];
              }
          }
          

          诀窍是设置

          cell.selectionStyle = UITableViewCellSelectionStyleDefault;
          

          在实现视图控制器中,然后在 tableViewCell 中将其设置为

          [self setSelectionStyle:UITableViewCellSelectionStyleNone];
          

          希望这会有所帮助。 :)

          【讨论】:

          • 我确认这很好用。在我的自定义单元格子类 initWithCoder 中,我将选择样式设置为 none,然后根据是否选择在 setSelected 中自定义颜色等。
          【解决方案11】:

          对于 iOS7+,如果您使用的是 Interface Builder,则子类化您的单元并实现:

          Objective-C

          - (void)awakeFromNib {
              [super awakeFromNib];
              // Default Select background
              UIView *v = [[UIView alloc] init];
              v.backgroundColor = [UIColor redColor];
              self.selectedBackgroundView = v;
          }
          

          斯威夫特 2.2

          override func awakeFromNib() {
              super.awakeFromNib()
              // Default Select background
              self.selectedBackgroundView = { view in
                  view.backgroundColor = .redColor()
                  return view
              }(UIView())
          }
          

          【讨论】:

            【解决方案12】:

            这与分组调用完美配合:实现UITableViewCell 的自定义子类

            这将尊重角落等......

            - (void)setSelected:(BOOL)selected animated:(BOOL)animated
            {
                [super setSelected:selected animated:animated];
            
                if(selected)
                    [self setBackgroundColor:[UIColor colorWithRed:(245/255.0) green:(255/255.0) blue:(255/255.0) alpha:1]];
                else
                    [self setBackgroundColor:[UIColor whiteColor]];
            
            }
            

            【讨论】:

            • 感谢这项工作,但不要忘记将 UITableViewCell "Selection" 设置为 "None" 而不是默认值,否则默认的灰色背景会一直显示。
            【解决方案13】:

            如果你只是想去除灰色的背景颜色,这样做:

            -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
            {
                 [[tableView cellForRowAtIndexPath:indexPath] setSelectionStyle:UITableViewCellSelectionStyleNone];
            }     
            

            【讨论】:

              【解决方案14】:

              默认样式为灰色,如果以编程方式完成,它会破坏单元格的颜色。你可以这样做来避免这种情况。 (斯威夫特)
              cell.selectionStyle = .None

              【讨论】:

              • swift 4 版本的解决方案是 cell?.selectionStyle = .none
              【解决方案15】:

              斯威夫特

              let v = UIView()
                  v.backgroundColor = self.darkerColor(color)
                  cell?.selectedBackgroundView = v;
              
              ...
              
              func darkerColor( color: UIColor) -> UIColor {
                  var h = CGFloat(0)
                  var s = CGFloat(0)
                  var b = CGFloat(0)
                  var a = CGFloat(0)
                  let hueObtained = color.getHue(&h, saturation: &s, brightness: &b, alpha: &a)
                  if hueObtained {
                      return UIColor(hue: h, saturation: s, brightness: b * 0.75, alpha: a)
                  }
                  return color
              }
              

              【讨论】:

              • 这绝对是最好的现代答案,因为将选择样式设置为 .None 并使用“willSelectRow”和“didSelectRow”委托方法具有长按一行不会突出显示的副作用它被选中,这是正常样式的默认行为。
              【解决方案16】:

              Apple's sample code 中查看AdvancedTableViewCells

              您需要使用复合单元格模式。

              【讨论】:

                【解决方案17】:

                为我工作

                UIView *customColorView = [[UIView alloc] init];
                    customColorView.backgroundColor = [UIColor colorWithRed:180/255.0 
                                                                      green:138/255.0 
                                                                       blue:171/255.0 
                                                                      alpha:0.5];
                    cell.selectedBackgroundView =  customColorView;
                

                【讨论】:

                  【解决方案18】:

                  在 Swift 3 中,从照亮答案转换而来。

                  override func setSelected(_ selected: Bool, animated: Bool) {
                      super.setSelected(selected, animated: animated)
                      if(selected) {
                          self.selectionStyle = .none
                          self.backgroundColor = UIColor.green
                      } else {
                          self.backgroundColor = UIColor.blue
                      }
                  }
                  

                  (但是只有在松开手指确认选择后视图才会改变)

                  【讨论】:

                    【解决方案19】:

                    Swift 5.3

                    这里我只为单行做了,没有为单元格创建一个类。

                    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                        if let cell = tableView.cellForRow(at: indexPath) {
                            cell.contentView.backgroundColor = #colorLiteral(red: 0.1411764771, green: 0.3960784376, blue: 0.5647059083, alpha: 1)
                        }
                    }
                    override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
                        if let cell = tableView.cellForRow(at: indexPath) {
                            cell.contentView.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
                        }
                    }
                    

                    【讨论】:

                    • 我正在寻找 OSX 解决方案。我可以更改单元格颜色,但无法隐藏/取消隐藏单元格内的按钮。有什么帮助吗?
                    【解决方案20】:

                    创建一个自定义 UITableViewCell。在您的自定义类中覆盖“setSelected”函数并更改 contentView 背景颜色。 你也可以重写你的“setHighlighted”函数。

                    在斯威夫特中:

                    class myTableViewCell: UITableViewCell {
                    
                        override func awakeFromNib() {
                            super.awakeFromNib()
                            // Initialization code
                        }
                    
                        override func setSelected(selected: Bool, animated: Bool) {
                            super.setSelected(selected, animated: animated)
                    
                            // Configure the view for the selected state
                            // Add your color here
                            self.contentView.backgroundColor = UIColor.whiteColor()
                        }
                    
                        override func setHighlighted(highlighted: Bool, animated: Bool) {
                            // Add your color here
                            self.contentView.backgroundColor = UIColor.whiteColor()
                        }
                    }
                    

                    【讨论】:

                      【解决方案21】:
                      override func setSelected(_ selected: Bool, animated: Bool) {
                          super.setSelected(selected, animated: animated)
                      
                          if selected {
                              self.contentView.backgroundColor = .black
                          } else {
                              self.contentView.backgroundColor = .white
                          }
                      }
                      

                      【讨论】:

                        【解决方案22】:

                        Swift 3、4、5 选择单元格背景颜色

                        1) 当用户点击单元格时只改变高亮颜色:

                        1.1) 单元类内部:

                        override func awakeFromNib() {
                            super.awakeFromNib()
                            // Initialization code
                        
                            let backgroundView = UIView()
                            backgroundView.backgroundColor = UIColor.init(white: 1.0, alpha: 0.1)
                            selectedBackgroundView = backgroundView
                        }
                        

                        1.2) 使用自定义单元格的 Viewcontroller

                        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                            tableView.deselectRow(at: indexPath, animated: true)
                        }
                        

                        2) 如果要为选定的单元格设置颜色:

                        override func setSelected(_ selected: Bool, animated: Bool) {
                            super.setSelected(selected, animated: animated)
                            // Configure the view for the selected state
                        
                            if selected {
                                self.backgroundColor = .darkGray
                            } else {
                                self.backgroundColor = .white
                            }
                        }
                        

                        【讨论】:

                          【解决方案23】:

                          这是在 Interface Builder 中(在故事板中)执行此操作的快速方法。将一个简单的 UIView 拖到 UITableView 的顶部,如 接下来将您单元的selectedBackgroundView Outlet 连接到此视图。您甚至可以将多个单元的插座连接到这一视图。

                          【讨论】:

                          • 不,这不划算。如果你这样做......每个单元格只有一个实例。您无法使用此解决方案选择多个项目
                          • 是的,这个方法看起来不错,但是视图被共享,当它跳转到下一个单元格时你会得到一个闪光
                          【解决方案24】:

                          对于通过子类化UITableViewCell 并使用其默认的selectedBackgroundView 设置颜色,iOS 7(及更高版本?)与UIAppearance(正确)工作的解决方案,看看在我对类似问题的回答here

                          【讨论】:

                            【解决方案25】:
                            - (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
                            {
                                UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
                                cell.contentView.backgroundColor = [UIColor yellowColor];
                            }
                            
                            - (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
                            {
                                UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
                                cell.contentView.backgroundColor = nil;
                            }
                            

                            【讨论】:

                              【解决方案26】:

                              我已经尝试了以上答案中的每一个,但没有一个最适合我,

                              然后我研究了一种本地提供的方法,它工作正常。

                              首先,将 cellSelectionStyle 设置为 None,然后选择此解决方案。

                              func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath?
                              {   
                                  let cell = tableView.cellForRow(at: indexPath);
                              
                                 //cell which is getting deselected, make whatever changes that are required to make it back normal        
                              
                                  cell.backgroundColor = kNormalColor;
                              
                                  return indexPath;
                              }
                              
                              func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath?
                              {
                                  let cell = tableView.cellForRow(at: indexPath);
                              
                                 //cell which is getting selected, make whatever changes that are required to make it selected        
                              
                                  cell.backgroundColor = kSelectedColor;
                              
                                  return indexPath;
                              }
                              

                              这种方法比其他方法的优势是:

                              1. 适用于多个单元格选择
                              2. 您可以根据需要更改任何元素,不仅是给定单元格在被选中和取消选中时的背景颜色。

                              【讨论】:

                                【解决方案27】:
                                var last_selected:IndexPath!
                                

                                在类中定义 last_selected:IndexPath

                                func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                                    let cell = tableView.cellForRow(at: indexPath) as! Cell
                                    cell.contentView.backgroundColor = UIColor.lightGray
                                    cell.txt.textColor = UIColor.red
                                
                                    if(last_selected != nil){
                                        //deselect
                                        let deselect_cell = tableView.cellForRow(at: last_selected) as! Cell
                                        deselect_cell.contentView.backgroundColor = UIColor.white
                                        deselect_cell.txt.textColor = UIColor.black
                                    }
                                
                                    last_selected = indexPath
                                }
                                

                                【讨论】:

                                • 我正在寻找 OSX 解决方案。我可以更改单元格颜色,但无法隐藏/取消隐藏单元格内的按钮。有什么帮助吗?
                                【解决方案28】:

                                将 selection 属性设置为 None,确保 tableView 设置了“Single Selection”并在tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell委托方法中使用此方法:

                                extension UITableViewCell {
                                    func setSelectionColor(isSelected: Bool, selectionColor: UIColor, nonSelectionColor: UIColor) {
                                        contentView.backgroundColor = isSelected ? selectionColor : nonSelectionColor
                                    }
                                }
                                

                                【讨论】:

                                  【解决方案29】:

                                  SWIFT 5.X
                                  accessoryType 为单元格更改时,它也可以工作

                                  extension UITableViewCell{
                                      var selectedBackgroundColor: UIColor?{
                                          set{
                                              let customColorView = UIView()
                                              customColorView.backgroundColor = newValue
                                              selectedBackgroundView = customColorView
                                          }
                                          get{
                                              return selectedBackgroundView?.backgroundColor
                                          }
                                      }
                                  }
                                  

                                  在 UIViewController 中使用如下...

                                  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                                      let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! myCell
                                      cell.selectedBackgroundColor = UIColor.lightGray
                                      return cell
                                    }
                                  

                                  【讨论】:

                                  • 我正在寻找 OSX 解决方案。我可以更改单元格颜色,但无法隐藏/取消隐藏单元格内的按钮。有什么帮助吗?
                                  【解决方案30】:

                                  我最近遇到了 Swift 5 更新的问题,其中表格视图会闪烁选择然后取消选择选定的单元格。我在这里尝试了几种解决方案,但都没有奏效。 解决方案是将clearsSelectionOnViewWillAppear 设置为false。

                                  我之前使用过 UIView 和 selectedBackgroundColor 属性,所以我继续使用这种方法。

                                  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                                    let cell = tableView.dequeueReusableCell(withIdentifier: "popoverCell", for: indexPath) as! PopoverCell
                                  
                                    let backgroundView = UIView()
                                    backgroundView.backgroundColor = Color.Blue
                                    cell.selectedBackgroundView = backgroundView
                                  }
                                  

                                  以下是我需要对 Swift 5 进行的更改。clearsSelectionOnViewWillAppear 属性是我的单元格取消选择的原因。首次加载时需要进行以下选择。

                                  override func viewDidLoad() {
                                    super.viewDidLoad()
                                  
                                    clearsSelectionOnViewWillAppear = false
                                    popoverTableView.selectRow(at: selectedIndexPath, animated: false, scrollPosition: .none)
                                  }
                                  

                                  【讨论】:

                                  • 我正在寻找 OSX 解决方案。我可以更改单元格颜色,但无法隐藏/取消隐藏单元格内的按钮。有什么帮助吗?
                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2011-09-24
                                  • 2013-04-12
                                  • 2021-10-31
                                  • 2015-10-09
                                  • 1970-01-01
                                  • 2016-05-27
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多