如何阻止我的 tableView 单元格重复使用其中的按钮?

Posted

技术标签:

【中文标题】如何阻止我的 tableView 单元格重复使用其中的按钮?【英文标题】:How can i stop my tableView cell from reusing the button inside it? 【发布时间】:2017-09-03 18:22:35 【问题描述】:

我在协议中有一个函数,它以 TableViewcell 作为参数。

protocol GoingButtonDelegate 
    func goingButtonPressed(cell: TableViewCell)


class TableViewCell: UITableViewCell 
    // Outlets
    @IBOutlet weak var goingButton: UIButton!

    var delegate: GoingButtonDelegate?

    @IBAction func goingButtonTapped(_ sender: Any) 
        delegate?.goingButtonPressed(cell: self)  
    

然后我转到我的 ViewController 并实现委托及其功能,即在点击时更改按钮的图像。 “goingSelected”是绿色图像,“goingDeselected”是红色图像。

这一切都很好,当点击一个单元格的按钮时,它会从红色变为绿色,反之亦然。但是,当单元格被重用时,单元格的按钮状态会持续存在并被重用于进入视图的新行。有没有办法阻止这种情况发生?

 extension ViewController: GoingButtonDelegate 
    func goingButtonPressed(cell: TableViewCell) 
        cell.goingButton.isSelected = !cell.goingButton.isSelected

        if cell.goingButton.isSelected == true 
            cell.goingButton.setImage(UIImage(named: "goingSelected"), for: UIControlState.selected)
         else if cell.goingButton.isSelected == false 
            cell.goingButton.setImage(UIImage(named: "goingDeselected"), for: UIControlState.normal)
        
    

【问题讨论】:

How to prevent UITableView from reuse custom cells Swift的可能重复 您不想避免重复使用单元格。这不是正确的解决方案。 【参考方案1】:

有可能

直接替换

let cell = tableView.dequeueReusableCell(withIdentifier: identifier,
  for: indexPath)

与:

let cell= Bundle.main.loadNibNamed(identifier, owner: self, options: nil)?[0]

但我认为您需要更改应用逻辑。

在你的单元格类中设置Images

class TableViewCell: UITableViewCell 
  override func awakeFromNib() 
    super.awakeFromNib()
    self.goingButton.setImage(UIImage(named: "goingDeselected"), for:.normal)
    self.goingButton.setImage(UIImage(named: "goingSelected"), for:.selected)
  

在方法 goingButtonPressed(cell: TableViewCell) 中将 cell 更改为您的对象 只需设置Bool 输入真或假

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
  ...
  cell.goingButton.isSelected = object.isSelected
  ...

【讨论】:

您不想这样做。不要避免重复使用单元格。 @rmaddy 我已经提供了更好的答案,那就是改变逻辑【参考方案2】:

您需要将选定的行存储在索引路径数组中,在此之前我认为您应该做一些增强......或者很多!

单元格本身应该处理它的按钮,控制器应该只跟踪所有单元格的状态。 将这两个属性添加到您的单元格中

class TableViewCell: UITableViewCell 
    var indexPath:IndexPath?
    var isSelected : Bool = false 
        didSet
            if isSelected 
                cell.goingButton.setImage(UIImage(named: "goingSelected"), for: UIControlState.normal)
             else 
                cell.goingButton.setImage(UIImage(named: "goingDeselected"), for: UIControlState.normal)
            
        
    
    // Outlets
    @IBOutlet weak var goingButton: UIButton!

    var delegate: GoingButtonDelegate?

    @IBAction func goingButtonTapped(_ sender: Any) 
        self.isSelected = !self.isSelected
        delegate?.goingButtonPressed(cell: self)  
    
    ..
    ...

并将选定的单元格存储在您的视图控制器中以跟踪每个单元格的状态。

extension ViewController: GoingButtonDelegate 
    var selectedCells = NSMutableArray()
    func goingButtonPressed(cell: TableViewCell) 
        if cell.isSelected 
            selectedCells.add(cell.indexPath)
         else 
            selectedCells.remove(cell.indexPath)
        
    

在您的“行单元格”方法中只需添加一个小改动

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier") as! TableViewCell
    cell.indexPath = indexPath
    cell.isSelected = selectedCells.contains(indexPath)
    ..
    ...
    return cell

【讨论】:

以上是关于如何阻止我的 tableView 单元格重复使用其中的按钮?的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止 UITableview 一次滚动多个单元格

TableView 交互阻止单元格中的动画

swift - 快速滚动时如何阻止tableview单元格出现故障和闪烁的图像?

选择单元格时,如何阻止 UIView 的背景颜色消失?

如何在 TableView 中添加不同的自定义单元格 [重复]

如何使用不可重复使用的表格视图单元格?