简体   繁体   English

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

[英]How to change image of imageview in tableview custom cell with pagination.

I am using a tableview in an app in which I have used pagination. 我在使用分页的应用程序中使用tableview。 The request is sent to the server and it returns items in batches of size 10. everything is working fine till now. 该请求被发送到服务器,并返回批量为10的项目。到目前为止,一切工作正常。 Now I have an imageview in my tableview cells (custom). 现在,我的tableview单元格(自定义)中有一个imageview。 I want that when the image of that imageview toggles when user taps on it. 我希望当用户点击该imageview的图像时切换它。 I tried this thing in the following way: 我通过以下方式尝试了此方法:

TableviewController: 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)
            }

        }
}

CustomCell: CustomCell:

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()
    }

Now the problem which I am facing is that if user taps the first the imageview on any cell it changes its image, but along with that every 4th cell changes it image. 现在,我面临的问题是,如果用户首先在任何单元格上点击imageview,它将更改其图像,但与此同时,第4个单元格将更改其图像。 For example, if I have tapped imageview of first cell its image is changed but image of cell 5, 9, 13... also get changed. 例如,如果我点击了第一个单元格的imageview,则其图像会更改,但单元格5、9、13 ...的图像也会更改。

What is wrong with my code? 我的代码有什么问题? Did I miss anything? 我有想念吗? It is some problem with indexPath.row due to pagination, but i don't know what is it exactly and how to solve it. 由于分页,indexPath.row出现了一些问题,但我不知道它到底是什么以及如何解决它。 I found a similar question but its accepted solution didn't work for me, so any help would be appreciated. 我发现了一个类似的问题,但是它可接受的解决方案对我不起作用,因此我们将不胜感激。

if you need to toggle image and after scrolling also that should be in last toggle state means you need to use an array to store index position and toggle state by comparing index position and scroll state inside cellfoeRowAtIndex you can get the last toggle state that is one of the possible way to retain the last toggle index even when you scroll tableview otherwise you will lost your last toggle position 如果您需要切换图像,并且在滚动之后也应该处于最后切换状态,则意味着您需要使用一个数组来存储索引位置和切换状态,方法是比较cellfoeRowAtIndex内的索引位置和滚动状态,您可以获得的最后一个切换状态是即使滚动tableview时仍可以保留最后一个切换索引的方法,否则将丢失最后一个切换位置

 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
     }

 }

Hope this will help you 希望这个能对您有所帮助

Your code looks OK, I see just one big error. 您的代码看起来不错,我只看到一个大错误。

When u are setting dynamic data (names, images, stuff that changes all the time) use func tableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath) not cellForRowAt indexPath . 当您设置动态数据(名称,图像,随时更改的内容)时,请使用func tableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath)而不是cellForRowAt indexPath

cellForRowAt indexPath should be used for static resources, and cell registration. cellForRowAt indexPath应该用于静态资源和单元格注册。

If u are on iOS 10 + take a look at prefetchDataSource gonna speed things up a loot, I love it. 如果您使用的是iOS 10以上版本,请查看prefetchDataSource加快速度,我喜欢它。 https://developer.apple.com/documentation/uikit/uitableview/1771763-prefetchdatasource https://developer.apple.com/documentation/uikit/uitableview/1771763-prefetchdatasource

Small example: 小例子:

here u register the cell, and set up all the stuff that is common for all the cells in the table view 在这里,您注册单元格,并设置表视图中所有单元格共有的所有内容

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

here adjust all the stuff that is object specific 在这里调整所有特定于对象的东西

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
}
}

You need this because cells get reused, and they have their own lifecycle, so you want to set specific data as late as possible, but you want to set the generic data as less as possible ( most of the stuff you can do once in cell init ). 您之所以需要这样做,是因为单元被重用,并且它们具有自己的生命周期,因此您希望尽可能晚地设置特定数据,但是您希望尽可能少地设置通用数据(大多数事情可以在单元中一次完成在里面 )。

Cell init is also a great place for generic data, but u can not put everything there 单元格初始化也是通用数据的好地方,但是您不能将所有内容放在那

Also, great thing about cell willDisplay is the that u know actual size of the frame at that point 另外,单元格willDisplay是您知道该点帧的实际大小

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM