简体   繁体   中英

My heart button state in TableViewCell is saved when the cell gets reused

I'm filling the table view using xib. Each cell has a button with a heart image which can be filled or not. When button is selected it adds the row where the button is to a favourite view. So far it's working. The problem is that when I scroll the table view the cell that gets reused is shown up with a filled heart instead of an empty one.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   if indexPath.row % 2 == 0 {
       let cellIdentifier = "cell"
       let cell = productTableView.dequeueReusableCell(withIdentifier: cellIdentifier ,for :indexPath)
           as! ProductsTableViewCell
       let model = productArray[indexPath.row]
       cell.favouriteButton.tag = indexPath.row
       cell.configureCell(model)

       return cell
   }else {
       let cellIdentifier = "cell2"
       let cell = productTableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! Product2TableViewCell
       let model = productArray[indexPath.row]
       cell.favouriteButton.tag = indexPath.row

       if favouriteProductsArray.count != 0 {
           for fave in favouriteProductsArray {
               if fave.product_id == model.id{
                   cell.favouriteButton.isSelected = true
               }
           }
       }else{
           cell.favouriteButton.isSelected = false
       cell.setupCell(model)
       return cell
   }
}

在此输入图像描述

I believe the problem is with the following code:

if favouriteProductsArray.count != 0 {
    for fave in favouriteProductsArray {
        if fave.product_id == model.id{
            cell.favouriteButton.isSelected = true
        }
    }
}else{
    cell.favouriteButton.isSelected = false
}

In the first if statement, you have no logic to set isSelected to false . I would redo that code as follows:

var selected = false
if favouriteProductsArray.count != 0 {
    for fave in favouriteProductsArray {
        if fave.product_id == model.id {
            selected = true
            break
        }
    }
}
cell.favouriteButton.isSelected = selected

This ensures isSelected is set to false unless you find a matching id.

I had a similar issue. What I did was have an array to track the .isSelected value, and after dequeuereusablecell set the isSelected based on the values in the array. This could just be an if statement.

So that would be an array of n elements, where n is the number of food items you are loading. Each element would be true or false, which is the respective value for isSelected, which is set after dequeuereusablecell.

While you properly set up the favorite button in the else part, you fail to do so when the if-condition is true. Do it there, too. Or better yet, extract the code to do it outside of the if statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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