Hanzala Raza
Hanzala Raza

Reputation: 149

Best Approach to make Calculation in tableviewcells and sums up in UILabel

My Cart looks like this

enter image description here

What should be the best approach to do calculation of all cells and sums up total Amount label

Cart Working like this :

Increment in cell's item doubles the value of price label but when i dequeue new cell it already has that increment value

When tried to work with custom delegate , Delegate always shows nil

What should I do ? why my delegate is always nil ?

TableViewCell

class ShoppingCartCell: UITableViewCell {


    @IBOutlet weak var cellView:UIView!
    @IBOutlet weak var productImageView:UIImageView!
    @IBOutlet weak var productName:UILabel!
    @IBOutlet weak var brandName:UILabel!
    @IBOutlet weak var productPrice:UILabel!
    @IBOutlet weak var modifier1Lbl:UILabel!
    @IBOutlet weak var modifier2Lbl:UILabel!
    @IBOutlet var counterBtns:[UIButton]!
    @IBOutlet weak var counterLbl:UILabel!


    var delegate : cellDelegateFunc?
    override func layoutMarginsDidChange() {
        super.layoutMarginsDidChange()
        contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))

        productImageView.layer.cornerRadius = productImageView.frame.height / 4
        cellView.roundUIViewWithShadow(cornerRadius: 4, shadowColor: .darkGray)
        cellView.layer.masksToBounds = false
        cellView.layer.shadowColor = UIColor.lightGray.cgColor
        cellView.layer.shadowOpacity = 1
        cellView.layer.shadowOffset = .zero

    }
    override func awakeFromNib() {
        super.awakeFromNib()

        cellView.layer.cornerRadius = cellView.frame.height / 16
        productImageView.layer.cornerRadius = productImageView.frame.height / 16
    }


    @IBAction func counter(_ sender:UIButton){

        self.delegate?.countItems(self)
    }

}

CartViewController (Particular Portion)

class ShoppingBagVC: UIViewController , cellDelegateFunc {
    func countItems(_ cell: ShoppingCartCell) {
        print("print")
    }
}

Protocol

protocol cellDelegateFunc : class {
    func countItems(_ cell:ShoppingCartCell)
}

CellForRow

   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if cartAllData[indexPath.row].deal.data != nil {
       let cell = cartTableView.dequeueReusableCell(withIdentifier: "cell3", for: indexPath) as! ShoppingCartDealCell
        cell.originalPrice = Int(cartAllData[indexPath.row].deal.data!.dealPrice)
        cell.productName.text = cartAllData[indexPath.row].deal.data?.dealName
        cell.productPrice.text = "Rs.\(String(cell.originalPrice))"
        cell.freeItem.text = cartAllData[indexPath.row].deal.data?.freeProduct
        cell.productImageView?.sd_setImage(with: URL(string: cartAllData[indexPath.row].deal.data!.imageURL), completed: nil)
        return cell
    } else {
         let cell = cartTableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath) as! ShoppingCartCell
        var originalPrice = Int()

                  var price : Int = 2{
                      didSet {
                          cell.productPrice.text = "Rs.\(String(price))"
                      }
                  }

                  var count : Int = 1{
                      didSet {
                          cell.counterLbl.text = String(count)
                          price = originalPrice * count
                      }
                  }



                  if let value = cartAllData[indexPath.row].deal.data?.quantity {
                      cell.counterLbl.text = String(value)
                  }
        if let value = cartAllData[indexPath.row].product.data?.quantity {
            cell.counterLbl.text = String(value)
        }
        originalPrice = Int(cartAllData[indexPath.row].product.data!.productBasePrice)
        cell.productPrice.text = "Rs.\(String(originalPrice))"
        cell.productName.text = cartAllData[indexPath.row].product.data?.productName
        cell.productImageView?.sd_setImage(with: URL(string: cartAllData[indexPath.row].product.data!.imageURL), completed: nil)
        cell.modifier1Lbl.text = cartAllData[indexPath.row].product.data?.modifier1
        cell.modifier2Lbl.text = cartAllData[indexPath.row].product.data?.modifier2
        return cell
    }


}

Upvotes: 1

Views: 192

Answers (1)

Hoven
Hoven

Reputation: 573

As @joakim said in comment you are doing calculations in a UI! and it's not a correct way

When a UITableView scrolls every cell will reload because of reusing and every cell will lose its state because it loads again. so you must store state of each cell in a Model and pass it to your cell each time a cell loads.

As you requested The Best approach would be to use a ViewModel or a Presenter to store state of a View (here your cell) and in every load you feed that View (for example in your cellForRow) with the stored States or Properties

Upvotes: 1

Related Questions