soRazor
soRazor

Reputation: 147

UILabel inside of UICollectionViewCell is not updating correctly

I have a "totalPrice" UILabel inside of a full page UICollectionViewCell. When I press add button it is supposed to add the price of the specific item on that cells totalPrice label. And when I press subtract it subtracts the total price. For some reason the third or sometimes fourth cell are displaying the wrong total price. My logic is wrong but I cannot pinpoint what the exact issue is.

  class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, PostCellDelegate {

    var totalPrice = Float()

    private var hiddenRows = Set<Int>()

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

    var totalPrice = Float()

    private var hiddenRows = Set<Int>()

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! PostCell

    cell.finalLabel.text = String(totalPrice)
    cell.delegate = self

    let item = itemsArr[indexPath.row]
    cell.set(name: item.name, brand: item.brand, price: item.price)

    if hiddenRows.contains(indexPath.row) {
        cell.myButton.isHidden = true
        cell.removeButton.isHidden = false
    }else{
        cell.removeButton.isHidden = true
        cell.myButton.isHidden = false
    }
    cell.finalLabel.text = String(totalPrice)
    return cell
}


@objc func addTapped(cell: PostCell) {

      guard let indexPath = self.collectionView.indexPath(for: cell)  else {return}
      hiddenRows.insert(indexPath.row)
      cell.removeButton.isHidden = false
      let item = itemsArr[indexPath.row]
      print(item.price)
      totalPrice += Float(item.price) ?? 0
      cell.finalLabel.text = String(totalPrice)
}


@objc func removeButtonTapped(cell: PostCell) {

    guard let indexPath = self.collectionView.indexPath(for: cell)  else {return}
    hiddenRows.insert(indexPath.row)
    cell.myButton.isHidden = false
    let item = itemsArr[indexPath.row]
    totalPrice -= Float(item.price) ?? 0
    cell.finalLabel.text = String(totalPrice)
 //   collectionView?.reloadData()
}
 }



protocol PostCellDelegate {
    func removeButtonTapped(cell: PostCell)
    func addTapped(cell: PostCell)
    func didPressButton(_ tag: Int)
}

class PostCell: UICollectionViewCell {

     var delegate: PostCellDelegate?

     func set(name: String, brand: String, price: String){
         nameLabel.text = name
         brandLabel.text = brand
         priceLabel.text = price
     }

     override init(frame: CGRect) {
         super.init(frame: frame)
        self.myButton.addTarget(self, action: #selector(addButtonTapped(sender:)), for: .touchUpInside)
        self.removeButton.addTarget(self, action: #selector(subButtonTapped(sender:)), for: .touchUpInside)
        setupCellConstraints()
    }

    @objc func buttonPressed(_ sender: UIButton) {
        delegate?.didPressButton(sender.tag)
    }


    @objc func addButtonTapped(sender: UIButton){
        self.delegate?.addTapped(cell: self)
        sender.isHidden = true
    }


    @objc func subButtonTapped(sender: UIButton){
        self.delegate?.removeButtonTapped(cell: self)
        sender.isHidden = true 
    }
}

Upvotes: 1

Views: 326

Answers (2)

Hamed
Hamed

Reputation: 1848

It is because of reusing cell remove total price

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    // remove this line
    //var totalPrice = Float()

    private var hiddenRows = Set<Int>()

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! PostCell
    //remove this line
    //cell.finalLabel.text = String(totalPrice)
    cell.delegate = self

    let item = itemsArr[indexPath.row]
    cell.set(name: item.name, brand: item.brand, price: item.price)

    if hiddenRows.contains(indexPath.row) {
      cell.myButton.isHidden = true
      cell.removeButton.isHidden = false
    }else{
      cell.removeButton.isHidden = true
      cell.myButton.isHidden = false
    }
    // remove this line
    //cell.finalLabel.text = String(totalPrice)
    return cell

}

keep current price in cell

class PostCell: UICollectionViewCell {
 var currentPrice: Float = 0
 var delegate: PostCellDelegate?
 func set(name: String, brand: String, price: String){
     nameLabel.text = name
     brandLabel.text = brand
     priceLabel.text = price
     finalLabel.text = "\(currentPrice)"
 }

. . .

}

Compute currentPrice

@objc func addTapped(cell: PostCell) {

  guard let indexPath = self.collectionView.indexPath(for: cell)  else {return}
  hiddenRows.insert(indexPath.row)
  cell.removeButton.isHidden = false
  let item = itemsArr[indexPath.row]
  print(item.price)
  cell.currentPrice += Float(item.price) ?? 0
  cell.finalLabel.text = String(cell.currentPrice)
}


@objc func removeButtonTapped(cell: PostCell) {

guard let indexPath = self.collectionView.indexPath(for: cell)  else {return}
hiddenRows.insert(indexPath.row)
cell.myButton.isHidden = false
let item = itemsArr[indexPath.row]
cell.currentPrice -= Float(item.price) ?? 0
  cell.finalLabel.text = String(cell.currentPrice)
}

Upvotes: 0

Sky Shadow
Sky Shadow

Reputation: 324

You should remove totalPrice and hiddenRows variables in the cellForItem function, maybe you can take it outside just not there. As it is always called whenever a cell will display, meaning it will return to its initial value as empty.

And also if you want your tableView to reflect your new data, the data source should be the one to be updated for the table view to reflect its data. Never edit the cell properties alone because it is reusable.

Thanks. Hope this helps.

Upvotes: 1

Related Questions