1

I have a data in tableview. I have two buttons + and -, i want to increase and decrease value on click of buttons. please check below image to understand exactly.

enter image description here

When i press on first cell's plus icon, the value is reflecting in last cell.

This is my code :-

import UIKit
struct Product {
 var price = 0
}

class TicketBookingVC: UIViewController , UITableViewDelegate,       UITableViewDataSource {

@IBOutlet weak var tblView: UITableView!
@IBOutlet weak var mainTblView: UIView!

var bookingDetails = NSDictionary()
var paymentDetails = NSDictionary()
var arrPaymentDetails = NSArray()
var productArray = [Product]()
var product : Product!
private var counterValue = 1
var productIndex = 0
var counterLbl = UILabel()

@IBOutlet weak var bookBtn: UIButton!
@IBOutlet weak var eventImg: UIImageView!


override func viewDidLoad() {
    super.viewDidLoad()

    tblView.delegate = self
    tblView.dataSource = self


    let payment = self.paymentDetails.value(forKey: "payment") as! NSArray
    self.arrPaymentDetails = payment as NSArray

    for _ in 0...10{
        productArray.append(Product(price: 1))
    }

    // Do any additional setup after loading the view.
}

func numberOfSections(in tableView: UITableView) -> Int {

    return 3
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if section == 0 {
        return 1
    }
    else if section == 1{
        return arrPaymentDetails.count
    }
    else{
        return 1
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if indexPath.section == 0 {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cellfirst", for: indexPath)


        cell.selectionStyle = .none
        return cell
    }
  else if indexPath.section == 1 {

       let cell = tableView.dequeueReusableCell(withIdentifier: "cellsecond", for: indexPath)

        let mainViewCell = cell.contentView.viewWithTag(2000) as! UIView
        let normalView = cell.contentView.viewWithTag(2001) as! UIView
        let eventName = cell.contentView.viewWithTag(2003) as! UILabel
        let eventPrice = cell.contentView.viewWithTag(2004) as! UILabel
        counterLbl = cell.contentView.viewWithTag(2007) as! UILabel
        let decrementBtn = cell.contentView.viewWithTag(2005) as! UIButton
        let incrementBtn = cell.contentView.viewWithTag(2006) as! UIButton

        let dictAllDetails = self.arrPaymentDetails.object(at: indexPath.row) as! NSDictionary
        print("dictallgroups : \(dictAllDetails)")

        if dictAllDetails.value(forKey: "label") != nil {

            eventName.text = dictAllDetails.value(forKey: "label") as! String
        }
        else{
            eventName.text = ""
        }

        if dictAllDetails.value(forKey: "price") != nil {

            eventPrice.text = "₹ \(dictAllDetails.value(forKey: "price") as! String)"
        }
        else{
            eventPrice.text = "₹ 0"
        }

        decrementBtn.addTarget(self, action:#selector(self.decrementbuttonClicked), for: .touchUpInside)
        incrementBtn.addTarget(self, action:#selector(self.incrementbuttonClicked), for: .touchUpInside)

        product = productArray[indexPath.row]
        counterLbl.text = "\(product.price)"
        productIndex = indexPath.row

       cell.selectionStyle = .none
       return cell
  }
    else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellthird", for: indexPath)


        cell.selectionStyle = .none
        return cell
    }
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    if indexPath.section == 0{

        return UITableView.automaticDimension
    }
    else{
        return 80
        //return UITableView.automaticDimension
    }
}

@objc func decrementbuttonClicked() {
    print("Button decrement")
    if(counterValue != 1){
        counterValue -= 1;
    }
    print("\(counterValue)")
    self.counterLbl.text = "\(counterValue)"
    product.price = counterValue
    print("\(product.price)")
    addProductToCart(product: product, atindex: productIndex)
}

@objc func incrementbuttonClicked() {
    print("Button increment")
    counterValue += 1;
    print("\(counterValue)")
    self.counterLbl.text = "\(counterValue)"
    product.price = counterValue
    print("\(product.price)")
    addProductToCart(product: product, atindex: productIndex)
}

func addProductToCart(product: Product, atindex: Int) {
    productArray[atindex] = product

    calculateTotal()
}

func calculateTotal()
{
    var totalValue = 0
    for objProduct in productArray {

        totalValue += objProduct.price
    }

   // self.totalLabel.text = "Total \(totalValue)"
}

}

I tried this link also :-

+/- quantity of products in Cart View Controller with buttons each on a TableViewCell, which gets default quantity as integer from an array

How do I increment/decrement a label value with two buttons pressed in tableview Swift

Thank you in advance.

Mayur Coceptioni
  • 433
  • 4
  • 17
  • This is because you are using the same variable to accumulate the count. Just like the name of the product, you should have in the dictionary a key to the quantity of each product and it must be increased / decremented – Claudio Castro Jul 15 '19 at 10:39
  • Unrelated but accessing views in cells by tags is outdated for a long, long time. Create a `custom` prototype cell in Interface Builder, add the UI elements, then create a custom class with IBOutlets, set the class of the custom cell to this class and connect the UI elements to the IBOutlets. And do not use `NSArray/NSDictionary` in Swift. You throw away the crucial type information. Use native types. – vadian Jul 15 '19 at 10:42
  • @ClaudioCastro let me try this. – Mayur Coceptioni Jul 15 '19 at 10:47
  • I think you'll find that the real problem is each cell is calling the increment/decrement method, but you have no way of knowing (currently) which cell the buttons are from. You are setting `productIndex` as you create each cell, but the last cell created isn't guaranteed to be the one the user clicks. You need to be able to workout from within those methods the cell row correctly – Flexicoder Jul 15 '19 at 10:51
  • @Flexicoder can you tell me with example, actually i am unable to understand your point of view. – Mayur Coceptioni Jul 15 '19 at 10:53
  • You will have to pass your index to the functions q increment / decrement to be able to know which product is being manipulated – Claudio Castro Jul 15 '19 at 10:54
  • @MayurCoceptioni - the second answer you linked too, has a good example answer https://stackoverflow.com/a/48304073/285190 – Flexicoder Jul 15 '19 at 10:55

2 Answers2

0

@Mayur Try this and make changes on selector of Increment and Decrement button.

func decrementbuttonClicked(sender : UIButton){
        if let cell = sender.superview?.superview as? UITableViewCell{ // use superview property till you cell not accessible here
            let counterLbl = cell.contentView.viewWithTag(2007) as! UILabel
            let intCounterValue = Int(counterLbl.text ?? "0") // fix error for conversion from strign to integer
            if(intCounterValue > 0){
                intCounterValue -= 1;
            }

            if let indexPath = tblViewCustomerInfo.indexPath(for: cell){
                let product = productArray[indexPath.row]
                product.price = intCounterValue
            }
        }
    }

func incrementbuttonClicked(sender : UIButton){
    if let cell = sender.superview?.superview as? UITableViewCell{ // use superview property till you cell not accessible here
        let counterLbl = cell.contentView.viewWithTag(2007) as! UILabel
        var intCounterValue = Int(counterLbl.text ?? "0") // fix error for conversion from strign to integer
        intCounterValue += 1;

        if let indexPath = tblViewCustomerInfo.indexPath(for: cell){
            let product = productArray[indexPath.row]
            product.price = intCounterValue
        }
    }
}
KKRocks
  • 8,222
  • 1
  • 18
  • 84
-1

Instead of defining counterValue as Int make it array[Int] and set the counter value according to index.

in cellforrowindexpath - define tag to buttons like. button.tag = index

and get it in your functional like -

@objc func incrementbuttonClicked(sender: UIButton) { index = sender.tag }

Abhishek
  • 329
  • 3
  • 12