iosswiftuicollectionviewprepareforreuse

UICollectionView | Cell reusable


SO, UICollectionView is being a real pain for me right now. Consider I have a UIViewController which has a UICollectionView embedded in it. Well each cell of the CollectionView is almost the entire width of the UIViewController. And each cell contains some buttons and images. When I select one button and tend to make the button retain its state, the CollectionView reuses the cell and kind of duplicates the cell states across other cells as well. However when I try to put the cells in an array and kind of want to check the states of cells in that array, the cellForItemAt method overwrites those cells. I am so confused. Please help. Even prepareForReuse in UICollectionViewCell isn't helping. Here is some code:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! AddressCollectionViewCell
    cell.shopAddressDetailLbl.text = ""
    cell.addressObj = addresses[indexPath.row]
    cell.configureCellForAddress(cell.addressObj)
    cell.cellTag = indexPath.row
    cell.cellDelegate = self
    if addressCells.contains(cell) == false {
        addressCells.append(cell)
    } else {
        if cell.isAddressConfirmed == true {
            cell.confirmAddress.setTitle("CONFIRMED", for: .normal)
            cell.confirmAddress.isEnabled = false
            cell.confirmAddress.backgroundColor
                = UIColor(red: 0, green: 100/255, blue: 0, alpha: 1)
            addressCells[indexPath.row] = cell
        }
    }
    return cell
}

extension AddressesCollectionViewController: AddressCollectionViewCellDelegate {
    func confirmBtnPressed(confirmAddressObj: Address, cell:AddressCollectionViewCell) {
        for cellTemp in addressCells {
            if cellTemp == cell && cellTemp.isAddressConfirmed == false {
                if let dele = addressCollectionViewDelegate {
                    cellTemp.isAddressConfirmed = true
                    dele.configureCellsAccordingToChanges(cell: cellTemp)
                }
            }
        }
    }
}

override func prepareForReuse() {
    super.prepareForReuse()

    cellTag = 0
    confirmAddress.setTitle("Confirm Address", for: .normal)
    confirmAddress.backgroundColor = APP_UNIVERSAL_COLOR
    confirmAddress.isEnabled = true
}

Any help is more than appreciated.


Solution

  • 🙌 @Vadian, @Abu Ul Hassan 👍

    Pretty slick! To others who need help in this regard. Vadian suggested in comments that I just need to update and monitor my model and thats exactly what I did. SO here it goes:

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! AddressCollectionViewCell
        cell.shopAddressDetailLbl.text = ""
        cell.addressObj = addresses[indexPath.row]
        cell.configureCellForAddress(cell.addressObj)
        cell.cellTag = indexPath.row
        cell.cellDelegate = self
    
        if addresses[indexPath.row].isConfirmed! == true {
            cell.confirmAddress.setTitle("CONFIRMED", for: .normal)
            cell.confirmAddress.isEnabled = false
            cell.confirmAddress.backgroundColor = UIColor(red: 0, green: 100/255, blue: 0, alpha: 1)
        } else {
            cell.confirmAddress.setTitle("Confirm Address", for: .normal)
            cell.confirmAddress.isEnabled = true
            cell.confirmAddress.backgroundColor = APP_UNIVERSAL_COLOR
        }
        return cell
    }
    
    extension AddressesCollectionViewController: AddressCollectionViewCellDelegate {
        func confirmBtnPressed(confirmAddressObj: Address, cell:AddressCollectionViewCell) {
            if confirmAddressObj.isConfirmed! == false {
                if let dele = addressCollectionViewDelegate {
                    cell.isAddressConfirmed = true
                    dele.configureCellsAccordingToChanges(cell: cell)
                }
            }
        }
    }
    

    And its ALIVE :D