【问题标题】:UITableViewCell Selected Background Color on Multiple SelectionUITableViewCell 多选时选定的背景颜色
【发布时间】:2015-01-09 19:13:15
【问题描述】:
// Doesn't work
cell.selectionStyle = .Blue
//Works when the selection is not multiple, if it's multiple with each selection the previous one disappear...
let cellBGView = UIView()
cellBGView.backgroundColor = UIColor(red: 0, green: 0, blue: 200, alpha: 0.4)
cell.selectedBackgroundView = cellBGView

任何答案如何设置被选中的单元格的背景颜色?

【问题讨论】:

  • 将背景视图设置为蓝色对我来说效果很好;当我选择它时,每个单元格都保持蓝色。您确定您的表格视图设置为多选吗?
  • 是的,选择是多个...当我点击单元格时,它会得到这个背景,但是当我点击另一个单元格时,它会改变颜色,但是,第一个点击的单元格的背景会恢复正常颜色.
  • cell.multipleSelectionBackgroundView = cellBGView //也不行...
  • 那个.... 听起来好像没有打开多选。你确定你打开了allowsMultipleSelection,而不是allowsMultipleSelectionDuringEditing
  • 我点击第一个单元格得到这个背景,当我点击另一个再次变蓝的单元格时,第一个单元格使用默认背景,但仍然被选中?

标签: ios uitableview swift selection selected


【解决方案1】:

以上所有答案都很好,但对我来说有点复杂。最简单的方法是在cellForRowAtIndexPath 中添加一些代码。这样您就不必担心在取消选择单元格时更改颜色。

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

    /* this is where the magic happens, create a UIView and set its
       backgroundColor to what ever color you like then set the cell's
       selectedBackgroundView to your created View */

    let backgroundView = UIView()
    backgroundView.backgroundColor = YOUR_COLOR_HERE
    cell.selectedBackgroundView = backgroundView
    return cell
}

【讨论】:

  • 我只是想保持简单
  • 这是一个很好的解决方案。我唯一改变的是将 backgroundView 声明移到函数之外,并将 backgroundView.backgroundColor 集移到 viewDidLoad 中。这样你就可以重复使用一个视图并且只设置一次颜色。诚然,这可能是过早的优化并分散了您的代码,但这是我的风格 ;-) 感谢您提供好的解决方案!
  • @DamienDelRusso 在这种情况下可以忽略 UIView 的初始化。如果您获得给定单元格的背景视图,您将遇到麻烦,因为您还将更新所有其他选定的背景视图,这不是预期的行为:P。我认为你应该避免你正在做的事情。
  • @OverD 是的,我的错误哈​​哈,我在单元格上一起禁用了选择。没注意到。它确实有效。
  • 我认为这完全取决于您放置代码的位置......显然,如果您希望更改某些单元格的背景颜色,您需要一些逻辑来获得您想要的行为。
【解决方案2】:

这对我有用:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var selectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
    selectedCell.contentView.backgroundColor = UIColor.redColor()
}

// if tableView is set in attribute inspector with selection to multiple Selection it should work.

// Just set it back in deselect 

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    var cellToDeSelect:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
    cellToDeSelect.contentView.backgroundColor = colorForCellUnselected
}


//colorForCellUnselected is just a var in my class

【讨论】:

  • 这对我来说看起来更好: if let cell = self.table.cellForRowAtIndexPath(path) as? ICComplaintCategoryCell { cell.contentView.backgroundColor = .redColor() }
  • Kersnowski 方法的问题在于,当重新绘制单元格时,选择/取消选择时所做的更改将消失。所以我会将更改移动到单元格本身,这意味着这里需要子类化。请检查我的代码以获取示例代码。
  • 重复使用后更改消失。
  • 我试过这个,我的单元格在被选中时会闪烁。我更喜欢 OverD 的不闪退的解决方案。请注意我的选择闪烁,因为我有一个深色调色板,所以 YMMV。
  • 现在不知道它当时是否有效,但是现在当我有一个大列表并且我尝试在didDeselectRow 方法中强制展开单元格时快速滚动我的应用程序中断时,我选择了 OverD 解决方案,并且仍然可以完美运行。
【解决方案3】:

斯威夫特 4.2

对于多选,您需要将UITableView 属性allowsMultipleSelection 设置为true

myTableView.allowsMultipleSelection = true

如果您将 UITableViewCell 子类化,则在自定义单元格类中覆盖 setSelected(_ selected: Bool, animated: Bool) 方法。

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

     if selected {
         contentView.backgroundColor = UIColor.green
     } else {
         contentView.backgroundColor = UIColor.blue
     }
 }

【讨论】:

    【解决方案4】:

    斯威夫特 3

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier", for: indexPath)
        cell.selectionStyle = .none
        return cell
    }
    

    斯威夫特 2

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
         let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier", for: indexPath)
         cell.selectionStyle = .None
         return cell
    }
    

    【讨论】:

    • 这是唯一合法的答案。其他答案会稍微延迟设置单元格的背景样式,或者删除单元格分隔符。
    【解决方案5】:

    Kersnowski 方法的问题在于,当重新绘制单元格时,选择/取消选择时所做的更改将消失。所以我会将更改移动到单元格本身,这意味着这里需要子类化。例如:

    class ICComplaintCategoryCell: UITableViewCell {
        @IBOutlet var label_title: UILabel!
        @IBOutlet var label_checkmark: UILabel!
    
        override func layoutSubviews() {
            super.layoutSubviews()
            reload()
        }
        func reload() {
            if isSelected {
                contentView.backgroundColor = UIColor.red
            }
            else if isHighlighted{
                contentView.backgroundColor = UIColor.red
            }
            else {
                contentView.backgroundColor = UIColor.white
            }
        }
    }
    

    在您的表视图委托中,只需调用reload

    if let cell = self.table.cellForRowAtIndexPath(path) as? ICComplaintCategoryCell {
        cell.reload()
    }
    

    为 Swift 3+ 更新,感谢@Bogy

    【讨论】:

    • isSelected替换为swift 3+
    • 这是迄今为止我见过的最干净的解决方案。
    • 很好的解决方案,只是一个问题:真的需要调用“cell.reload()”吗?我只是在 LayoutSubview() 中调用了 reload(),一切看起来都很好......我错过了什么吗?
    • @Hardy_Germany 如果我没记错的话,那时没有调用 cell.reload(),如果来回滚动表格视图,可能会发生奇怪的事情。如果现在没有它可以正常工作,则无需拨打电话。
    【解决方案6】:

    您还可以在界面生成器中将单元格的selectionStyle 设置为.none。与@AhmedLotfy 提供的解决方案相同,仅来自 IB。

    【讨论】:

      【解决方案7】:

      对于 Swift 3,4 和 5,您可以通过两种方式做到这一点。

      1) 类:UITableViewCell

      override func awakeFromNib() {
          super.awakeFromNib()
          //Costumize cell
      
          selectionStyle = .none
      }
      

      2) tableView cellForRowAt

          cell.selectionStyle = .none
      

      如果您想为特定单元格设置选择颜色,请查看以下答案: https://stackoverflow.com/a/56166325/7987502

      【讨论】:

        【解决方案8】:

        UITableViewCell 有一个属性multipleSelectionBackgroundViewhttps://developer.apple.com/documentation/uikit/uitableviewcell/1623226-selectedbackgroundview

        只需创建一个UIView 定义您选择的.backgroundColor 并将其分配给您的单元格.multipleSelectionBackgroundView 属性。

        【讨论】:

        • 感谢您的纠正,我不是故意传播错误信息。我已经调整了答案。
        • 感谢您编辑和修复您的答案。发生错误,没有问题。 :)
        【解决方案9】:

        斯威夫特 3

        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
             let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath)!
             selectedCell.contentView.backgroundColor = UIColor.darkGray
        }
        
        func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
             let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath)!
             selectedCell.contentView.backgroundColor = UIColor.clear
        }
        

        【讨论】:

          【解决方案10】:

          通过添加具有您自己的背景颜色的自定义视图,您可以在表格视图中自定义选择样式。

          let customBGColorView = UIView()
          customBGColorView.backgroundColor = UIColor(hexString: "#FFF900")
          cellObj.selectedBackgroundView = customBGColorView
          

          在 TableView 的 cellForRowAt 方法中添加这 3 行代码。 我在 UIColor 中使用了一个扩展来使用十六进制代码添加颜色。将此扩展代码放在任何类的末尾(在类的主体之外)。

          extension UIColor {    
          convenience init(hexString: String) {
              let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
              var int = UInt32()
              Scanner(string: hex).scanHexInt32(&int)
              let a, r, g, b: UInt32
              switch hex.characters.count {
              case 3: // RGB (12-bit)
                  (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
              case 6: // RGB (24-bit)
                  (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
              case 8: // ARGB (32-bit)
                  (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
              default:
                  (a, r, g, b) = (255, 0, 0, 0)
              }
              self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255)
            }
          }
          

          【讨论】:

            【解决方案11】:

            SWIFT 3/4

            CustomCell.selectionStyle = .none 的解决方案如果您设置了其他样式,您会看到“混合”背景颜色与灰色或蓝色。

            别忘了! func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)CustomCell.selectionStyle = .none 时没有调用。

            extension MenuView: UITableViewDelegate {
                func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                    let cellType = menuItems[indexPath.row]
                    let selectedCell = tableView.cellForRow(at: indexPath)!
                        selectedCell.contentView.backgroundColor = cellType == .none ? .clear : AppDelegate.statusbar?.backgroundColor?.withAlphaComponent(0.15)
            
                    menuItemDidTap?(menuItems[indexPath.row])
            
                    UIView.animate(withDuration: 0.15) {
                        selectedCell.contentView.backgroundColor = .clear
                    }
                }
            }
            

            【讨论】:

              【解决方案12】:

              Swift 5 - 这对我有用:

               func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
              
                      let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath as IndexPath)!
                      selectedCell.contentView.backgroundColor = .red
                  }
              
              
              
                  func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
              
                      let cellToDeSelect:UITableViewCell = tableView.cellForRow(at: indexPath as IndexPath)!
                      cellToDeSelect.contentView.backgroundColor = .clear
                  }
              

              【讨论】:

                【解决方案13】:

                你可以使用标准的 UITableViewDelegate 方法

                - (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
                    EntityTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
                    [cell selectMe];
                    return indexPath;
                }
                
                - (nullable NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
                    EntityTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
                    [cell deSelectMe];
                    return indexPath;
                }
                

                在我的情况下,这是可行的,因为我们需要选择单元格,更改颜色,并且当用户在选定的单元格上点击 2 次时,应该执行进一步的导航。

                【讨论】:

                  【解决方案14】:

                  斯威夫特 4

                  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
                  {
                      let selectedCell = tableView.cellForRow(at: indexPath)! as! LeftMenuCell
                      selectedCell.contentView.backgroundColor = UIColor.blue
                  }
                  

                  如果你想取消选择前一个单元格,你也可以使用不同的逻辑

                  var tempcheck = 9999
                  var lastrow = IndexPath()
                  var lastcolor = UIColor()
                  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
                  {
                      if tempcheck == 9999
                      {
                          tempcheck = 0
                          let selectedCell = tableView.cellForRow(at: indexPath)! as! HealthTipsCell
                          lastcolor = selectedCell.contentView.backgroundColor!
                          selectedCell.contentView.backgroundColor = UIColor.blue
                          lastrow = indexPath
                      }
                      else
                      {
                          let selectedCelllasttime = tableView.cellForRow(at: lastrow)! as! HealthTipsCell
                          selectedCelllasttime.contentView.backgroundColor = lastcolor
                          let selectedCell = tableView.cellForRow(at: indexPath)! as! HealthTipsCell
                          lastcolor = selectedCell.contentView.backgroundColor!
                          selectedCell.contentView.backgroundColor = UIColor.blue
                          lastrow = indexPath
                      }
                  }
                  

                  【讨论】:

                  • 如何使用单选并取消选择其他
                  • 您可以使用不同类型的登录,因此您可以使用它,我为此检查添加了额外的代码
                  猜你喜欢
                  • 1970-01-01
                  • 2015-11-01
                  • 2015-06-11
                  • 1970-01-01
                  • 2012-06-05
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多