Evelyn
Evelyn

Reputation: 186

Having multiple buttons in cell that pass selected buttons set data to cell

I have three buttons in my cell that have a price and weight label, what im trying to do is have the selected optionBtn pass the weight and price data to the CartVC

the code that I currently have in the in the CartCell does not yet post the data for the selected optionBtn's weight and price labels

the function func configure that I have set in the CartCell works in presenting data in the cells for the CartVC

Where the cart does show the name, category, & image when the atcBtn is pressed to pass the data to the CartVC

What I want is to show the selected optionBtn price and weight (when selected) in the the CartVC cells how would I be able to modify the code I have set for the optionBtns in the func

import UIKit
import SDWebImage
import Firebase

class Cell: UITableViewCell {

    weak var items: Items!    
    @IBOutlet weak var name: UILabel!
    @IBOutlet weak var category: UILabel!
    @IBOutlet weak var productImage: UIImageView!   
    @IBOutlet weak var weightOne: UILabel!
    @IBOutlet weak var weightTwo: UILabel!
    @IBOutlet weak var weightThree: UILabel!
    @IBOutlet weak var priceOne: UILabel!
    @IBOutlet weak var priceTwo: UILabel!
    @IBOutlet weak var priceThree: UILabel!

    @IBOutlet weak var addToCart: RoundButton!

    @IBOutlet weak var optionBtn1: RoundButton!
    @IBOutlet weak var optionBtn2: RoundButton!
    @IBOutlet weak var optionBtn3: RoundButton!

    var addActionHandler: (() -> Void)?

    func configure(withItems items: Items) {
        name.text = items.name
        category.text = items.category
        image.sd_setImage(with: URL(string: items.image))
        priceOne.text = items.price1
        priceTwo.text = items.price2
        priceThree.text = items.price3
        weightOne.text = items.weight1
        weightTwo.text = items.weight2
        weightThree.text = items.weight3
    }
    @IBAction func atcBtn(_ sender: UIButton) {
        self.addActionHandler?()
    }   
}

import UIKit
import Firebase
import FirebaseFirestore

class ViewController: UITableViewController {

    @IBOutlet weak var cartButton: BarButtonItem!!
    @IBOutlet weak var tableView: UITableView!

    var itemSetup: [Items] = []

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return itemSetup.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? Cell else { return UITableViewCell() }

        let item = itemSetup[indexPath.row]
        cell.configure(withItem: item)
        cell.addActionHandler = {
             Cart.currentCart.items.append(item)
        }
        return cell
    }

}

class CartViewController: UIViewController {

    var items: Items!
    @IBOutlet weak var cartTableView: UITableView!

     override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        cartTableView.dataSource = self
        cartTableView.delegate = self
    }

}

extension CartViewController: UITableViewDataSource, UITableViewDelegate {

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Cart.currentCart.cartItems.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CartCell", for: indexPath) as! CartCell

        let cart = Tray.currentCart.cartItems[indexPath.row]
        cell.configure(withItems: cart)

        return cell
    }
}

class CartCell: UITableViewCell {

    var selctedBtn: Cell?

    @IBOutlet weak var lblMealName: UILabel!
    @IBOutlet weak var imageUrl: UIImageView!
    @IBOutlet weak var lblSubTotal: UILabel!
    @IBOutlet weak var lblWeight: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    var lastSelectedButton = UIButton()
    func configure(withItems items: Items) {
        // lblWeight.text = "\(items.weight1)"
        // lblSubTotal.text = "$\(formatter.string(for: items.price1)!)"
        lblMealName.text = "\(items.category): \(items.name)"
        let formatter = NumberFormatter()
        formatter.maximumFractionDigits = 2
        formatter.numberStyle = .decimal
        imageUrl.sd_setImage(with: URL(string: items.imageUrl))

        // optionBtns I dont know how to set the code to where I can individual
        //  select a btn to pass the data to the cell
        if selctedBtn?.optionBtn1.isSelected == true {
            lblSubTotal.text = "$\(formatter.string(for: items.price1)!)"
            lblWeight.text = "\(items.weight1)"            

        } else if selctedBtn?.optionBtn2.isSelected == true {
            lblSubTotal.text = "$\(formatter.string(for: items.price2)!)"
            lblWeight.text = "\(items.weight2)"

        } else if selctedBtn?.optionBtn3.isSelected == true {
            lblSubTotal.text = "$\(formatter.string(for: items.price3)!)"
            lblWeight.text = "\(items.weight3)"

        }

       // or this

       switch lastSelectedButton {
    case selctedBtn!.optionBtn1:
        isSelected = true
        lblSubTotal.text = "$\(formatter.string(for: items.price1)!)"
        lblWeight.text = "\(items.weight1)"
    case selctedBtn!.optionBtn2:
        isSelected = true
        lblSubTotal.text = "$\(formatter.string(for: items.price2)!)"
        lblWeight.text = "\(items.weight2)"
    case selctedBtn!.optionBtn3:
        isSelected = true
        lblSubTotal.text = "$\(formatter.string(for: items.price3)!)"
        lblWeight.text = "\(items.weight3)"
    default:
        break
    }
    }  

 // still running tests to make this work just can't seem to have the selected buttons data pass to the Cart Cells
}

Update:

just added some code that I have been testing still no luck in how to pass the label to the cart after the option button is selected

Upvotes: 0

Views: 581

Answers (1)

DonMag
DonMag

Reputation: 77682

You can pass back values in closures.

So, in your Cell class (naming is confusing to discuss - make it something like SelectItemCell), you could change your closure var to:

var addActionHandler: ((Int) -> Void)?

Then, in your addToCart button action, something along these lines:

@IBAction func atcBtn(_ sender: UIButton) {

    // pass back the user selected values
    var i = 0
    switch lastSelectedButton {
    case optionBtn1:
        i = 1
    case optionBtn2:
        i = 2
    default:
        i = 3
    }
    self.addActionHandler?(i)

}

That's rather awkward, and presumably you will be tracking actual values, but for example purposes this will work.

Now, in your VC that holds that table, in cellForRowAt, instead of your current:

    cell.addActionHandler = {
         Cart.currentCart.items.append(item)
    }

assign the closure like this:

    cell.addActionHandler = { (option: Int) in
        print("Option selected = \(option)")
        // do something based on the option that was selected
        // maybe item.selectedOption = option
        Cart.currentCart.items.append(item)
    }

If you want to pass back more than one value, add parameters:

var addActionHandler: ((Int, Int) -> Void)?

and in your button action:

self.addActionHandler?(priceVal, weightVal)

and your closure becomes:

    cell.addActionHandler = { (price: Int, weight: Int) in
        // use price and weight vars
        // ...
    }

Edit

If you don't already have a .selectedOption property of your Items class, you should add one (of type Int). You can use that to track the user's selection.

Change your cellForRowAt func along these lines:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? Cell else { return UITableViewCell() }

    // use var to make item mutable
    var item = itemSetup[indexPath.row]

    // pass item to cell to configure labels / buttons / etc
    cell.configure(withItem: item)

    // when the "add to cart" button in the cell is tapped
    cell.addActionHandler = { (option: Int) in

    // option will be 1, 2 or 3, indicating which button the user tapped
    print("Option selected = \(option)")

        // update the .selected property of your data
        item.selectedOption = option

        Cart.currentCart.items.append(item)
    }

    return cell
}

Now, in your CartCell in your CartViewController, you can fill in the labels like this:

    if items.selectedOption == 1 {
        lblSubTotal.text = "$\(formatter.string(for: items.price1)!)"
        lblWeight.text = "\(items.weight1)"            

    } else if items.selectedOption == 2 {
        lblSubTotal.text = "$\(formatter.string(for: items.price2)!)"
        lblWeight.text = "\(items.weight2)"

    } else if items.selectedOption == 3 {
        lblSubTotal.text = "$\(formatter.string(for: items.price3)!)"
        lblWeight.text = "\(items.weight3)"

    }

Upvotes: 1

Related Questions