Reputation: 186
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
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