如何使用分页更改 tableview 自定义单元格中的 imageview 图像。

Posted

技术标签:

【中文标题】如何使用分页更改 tableview 自定义单元格中的 imageview 图像。【英文标题】:How to change image of imageview in tableview custom cell with pagination. 【发布时间】:2017-11-23 10:36:05 【问题描述】:

我在使用了分页的应用程序中使用了表格视图。请求被发送到服务器,它以 10 个大小的批次返回项目。到目前为止一切正常。现在我的表格视图单元格(自定义)中有一个图像视图。我想要当用户点击它时该图像视图的图像切换时。我通过以下方式尝试了这个东西:

TableviewController:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        guard let cell :  AdventureTableViewCell = tableView.dequeueReusableCell(withIdentifier: "adventureCell" , for: indexPath) as? AdventureTableViewCell  else 
            fatalError("The dequeued cell is not an instance of AdventureViewCell.")
        

        cell.adventureName.text = adventureList[indexPath.row]
        cell.amountLabel.text = "\(adventurePriceList[indexPath.row])$"

        cell.favouriteButtonHandler = ()-> Void in
            if(cell.favouriteButton.image(for: .normal) == #imageLiteral(resourceName: "UnselectedFavIcon"))
            
                cell.favouriteButton.setImage(#imageLiteral(resourceName: "FavSelectedBtnTabBar"), for: .normal)
            
            else
            
                cell.favouriteButton.setImage(#imageLiteral(resourceName: "UnselectedFavIcon"), for: .normal)
            

        

自定义单元:

class AdventureTableViewCell: UITableViewCell 

    @IBOutlet weak var adventureName: UILabel!
    @IBOutlet weak var adventureImage: UIImageView!
    @IBOutlet weak var amountLabel: UILabel!
    @IBOutlet weak var favouriteButton: UIButton!
    @IBOutlet weak var shareButton: UIButton!

    var favouriteButtonHandler:(()-> Void)!
    var shareButtonHandler:(()-> Void)!

    override func awakeFromNib() 
        super.awakeFromNib()
        adventureName.lineBreakMode = .byWordWrapping
        adventureName.numberOfLines = 0
    

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

    override func prepareForReuse() 
        adventureImage.af_cancelImageRequest()
        adventureImage.layer.removeAllAnimations()
        adventureImage.image = nil
    

    @IBAction func favouriteButtonTapped(_ sender: Any) 
        self.favouriteButtonHandler()
    

现在我面临的问题是,如果用户点击任何单元格上的第一个图像视图,它会更改其图像,但随之而来的是每第四个单元格都会更改其图像。 例如,如果我点击了第一个单元格的图像视图,它的图像会改变,但单元格 5、9、13 的图像......也会改变。

我的代码有什么问题?我错过了什么吗?由于分页,indexPath.row 存在一些问题,但我不知道它到底是什么以及如何解决它。我发现了一个类似的问题,但它接受的解决方案对我不起作用,因此我们将不胜感激。

【问题讨论】:

【参考方案1】:

如果您需要切换图像并且在滚动之后也应该处于最后一个切换状态意味着您需要使用数组来存储索引位置和切换状态,通过比较cellfoeRowAtIndex 内的索引位置和滚动状态,您可以获得最后一个切换状态是保留最后一个切换索引的可能方法之一,即使您滚动表格视图,否则您将丢失最后一个切换位置

 if self.toggleStatusArray[indexPath.row]["toggle"] as! String == "on"
    cell.favouriteButton.setImage(#imageLiteral(resourceName: "FavSelectedBtnTabBar"), for: .normal)
  else 
    cell.favouriteButton.setImage(#imageLiteral(resourceName: "UnselectedFavIcon"), for: .normal)
 


cell.favouriteButtonHandler = ()-> Void in

    if self.toggleStatusArray[indexPath.row]["toggle"] as! String == "on"
    //Assign Off status to particular index position in toggleStatusArray

     else 

       //Assign on status to particular index position in toggleStatusArray
     

 

希望对你有帮助

【讨论】:

不完全是,但你的逻辑帮助我建立了自己的逻辑,我的问题得到了解决。因此,我将您的答案标记为已接受。谢谢:)【参考方案2】:

您的代码看起来不错,我只看到一个大错误。

当您设置动态数据(名称、图像、一直在变化的东西)时,使用func tableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath) 而不是cellForRowAt indexPath

cellForRowAt indexPath 应该用于静态资源和单元注册。

如果您使用的是 ios 10 + 看看 prefetchDataSource 会加快战利品的速度,我喜欢它。 https://developer.apple.com/documentation/uikit/uitableview/1771763-prefetchdatasource

小例子:

在这里你注册单元格,并设置所有表格视图中所有单元格共有的东西

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

在这里调整所有对象特定的东西

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
cell.nameLabel.text = model[indexPath.row].name
// also all the specific UI stuff goes here
if model[indexPath.row].age > 3 
    cell.nameLabel.textColor = .green
 else 
    cell.nameLabel.textColor = .blue


您需要这个,因为单元格可以重复使用,并且它们有自己的生命周期,因此您希望尽可能晚地设置特定数据,但您希望尽可能少地设置通用数据(大部分您可以做的事情一次在单元格初始化中)。

单元格初始化也是通用数据的好地方,但你不能把所有东西都放在那里

此外,单元格willDisplay 的好处在于您知道此时框架的实际大小

【讨论】:

我应该将哪些行转移到这个函数?你能提供一个编码示例吗? 我在原始答案中添加了一些东西,看看。

以上是关于如何使用分页更改 tableview 自定义单元格中的 imageview 图像。的主要内容,如果未能解决你的问题,请参考以下文章

在这种情况下,如何使用自定义 tableView 单元格处理可重用单元格(从代码中的其他位置更改单元格背景颜色不起作用)

Swift中带有标题的TableView的自定义分页大小(一次滚动一个单元格)

如何在一个自定义tableView单元格中使用两个按钮?我想在单击一个按钮时更改它们的图标

tableView 单元格高度...如何自定义?

如何在使用 tableViews 自调整单元格时在运行时更改表格视图单元格高度?

如何更改自定义单元格的 UILabel 文本?