UITableViewCell 图像在滚动时消失

Posted

技术标签:

【中文标题】UITableViewCell 图像在滚动时消失【英文标题】:UITableViewCell images disappear when scrolling 【发布时间】:2017-08-11 08:05:53 【问题描述】:

我在 UITableViewCell 中有一个 UIButton,一旦点击按钮,图像就会发生变化。尽管选定的按钮按预期被选中,但一旦 UITableView 滚动,选定的图像就会消失,因为单元格被重复使用。

我在编写逻辑时遇到问题。请帮忙。

我的代码在下面,在 Swift 3 中。

CellForRow:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    //Button_Action
    addSongButtonIdentifier(cell: cell, indexPath.row)

这是创建单元格的地方:

func addSongButtonIdentifier(cell: UITableViewCell, _ index: Int) 
    let addButton = cell.viewWithTag(TABLE_CELL_TAGS.addButton) as! UIButton

    //accessibilityIdentifier is used to identify a particular element which takes an input parameter of a string

    //assigning the indexpath button
    addButton.accessibilityIdentifier = String (index)
    // print("visible Index:",index)
    print("Index when scrolling :",addButton.accessibilityIdentifier!)

    addButton.setImage(UIImage(named: "correct"), for: UIControlState.selected)
    addButton.setImage(UIImage(named: "add_btn"), for: UIControlState.normal)

    addButton.isSelected = false
    addButton.addTarget(self, action: #selector(AddToPlaylistViewController.tapFunction), for:.touchUpInside)

点击功能:

func tapFunction(sender: UIButton) 
    print("IndexOfRow :",sender.accessibilityIdentifier!)
    // if let seporated by a comma defines, if let inside a if let. So if the first fails it wont come to second if let


    if let rowIndexString =  sender.accessibilityIdentifier, let rowIndex = Int(rowIndexString) 
    self.sateOfNewSongArray[rowIndex] = !self.sateOfNewSongArray[rowIndex]//toggle the state when tapped multiple times
    
    sender.isSelected = !sender.isSelected //image toggle
    print(" Array Data: ", self.sateOfNewSongArray)

    selectedSongList.removeAll()

    for (index, element) in self.sateOfNewSongArray.enumerated() 
        if element
            print("true:", index)

            selectedSongList.append(songDetailsArray[index])

            print("selectedSongList :",selectedSongList)
        
    

【问题讨论】:

不要多次问同一个问题。 ***.com/questions/45627323/… Selected button of a UITableViewCell get disappear when scrolling的可能重复 【参考方案1】:

addButton.isSelected = false 行的func addSongButtonIdentifier(cell: UITableViewCell, _ index: Int) 函数存在逻辑错误

应该是addButton.isSelected = self.sateOfNewSongArray[index]

由于每次滚动表格时都会调用 cellForRowAtIndexpath 方法,它正在重置 'addButton' 的选中状态

【讨论】:

【参考方案2】:

您需要有一个数组来存储选择的索引,就像您拥有的 selectedSongList 数组一样。然后在您的 cellForRow 方法中,您需要使用该数组中的 bool proparty 为您的按钮提供选择或取消选择状态,或者在您的 addSongButtonIdentifier 方法中选择状态需要是

addButton.isSelected = selectedSongList.contains(indexPath.row)

【讨论】:

【参考方案3】:

创建一个用于填充 UITableView 的模型类,并在该模型中获取 UIImage 变量,它将保存单元格的当前图像。单击按钮操作只需将 UIImage 变量更改为当前图像。

【讨论】:

【参考方案4】:

最好的方法是使用模型类并跟踪单元格中的每个单独元素。但是让我给你一个快速的解决方法。

像这样在任何地方创建一个自定义的 Button 类。

class classname: UIButton var imageName: String?

进入你的故事板,将类从 UIButton 更改为类名

在你的 tableViewCellForIndexPath 中

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
     let addButton = cell.viewWithTag(TABLE_CELL_TAGS.addButton) as! classname

     if let imgName = addButton.imageName 
      addButton.setImage(UIImage(named: imgName), for: UIControlState.normal)
      else 
       addButton.setImage(UIImage(named: "add_btn"), for:UIControlState.normal)
      
     addButton.addTarget(self, action: #selector(AddToPlaylistViewController.tapFunction), for:.touchUpInside)
 return cell
 

现在让我们转到您的点击按钮实现

func tapFunction(sender: classname)

print("IndexOfRow :",sender.accessibilityIdentifier!)
// if let seporated by a comma defines, if let inside a if let. So if the first fails it wont come to second if let


if let rowIndexString =  sender.accessibilityIdentifier, let rowIndex = Int(rowIndexString) 
self.sateOfNewSongArray[rowIndex] = !self.sateOfNewSongArray[rowIndex]//toggle the state when tapped multiple times

sender.imageName = sender.imageName == "correct" ? "add_btn" : "correct" //image toggle
sender.setImage(UIImage(named: sender.imageName), for:UIControlState.normal)

print(" Array Data: ", self.sateOfNewSongArray)

selectedSongList.removeAll()

for (index, element) in self.sateOfNewSongArray.enumerated() 
    if element
        print("true:", index)

        selectedSongList.append(songDetailsArray[index])

        print("selectedSongList :",selectedSongList)
    




【讨论】:

以上是关于UITableViewCell 图像在滚动时消失的主要内容,如果未能解决你的问题,请参考以下文章

滚动时 UITableViewCell 的奇怪行为,UIButtons 消失

UITableViewCell 的 UIButton 在滚动时消失

UITableViewCell 中的 UIScrollview 和维护滚动视图页面

滚动时更新 UITableViewCell

自定义 UITableViewCell 阴影消失

滚动时 UITableViewCell 图像发生变化