Reputation: 125
I have created this using UICollectionView When I click the Add(+)
or Remove(-)
button then I want to update the label. How can I achieve this?
MainViewController.swift
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if(collectionView == ProductCollectionView){
let Productcell = self.ProductCollectionView.dequeueReusableCell(withReuseIdentifier:"ProductCollectionViewCell", for: indexPath) as! ProductCollectionViewCell
Productcell.AddOrMinusLabel.text = "\(bestOfferProductCount[indexPath.row])"
Productcell.ProdName.text = bestOfferProductName[indexPath.row]
Productcell.ProdPrice.text = bestOfferProductPrice[indexPath.row]
Productcell.ProdtOrgPrice.text = bestOfferProductOriginalPrice[indexPath.row]
Productcell.ProdWeight.text = bestOfferProductWeight[indexPath.row]+" "+bestOfferProductUnit[indexPath.row]
Productcell.ProductImage.setImageFromURl(stringImageUrl: bestOfferProductImage[indexPath.row])
return Productcell
}
}
ProductCollectionViewCell.swift
import UIKit
class ProductCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var ProdPrice: UILabel!
@IBOutlet weak var ProdtOrgPrice: UILabel!
@IBOutlet weak var ProductImage: UIImageView!
@IBOutlet weak var ProdName: UILabel!
@IBOutlet weak var ProdWeight: UILabel!
}
Upvotes: 2
Views: 2496
Reputation: 558
I would do this using protocols, Add this to your cell's class and add the IBAction's to UIButton.
class ProductCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var ProdPrice: UILabel!
@IBOutlet weak var ProdtOrgPrice: UILabel!
@IBOutlet weak var ProductImage: UIImageView!
@IBOutlet weak var ProdName: UILabel!
@IBOutlet weak var ProdWeight: UILabel!
weak open var delegate: ProductCollectionViewCellDelegate?
@IBAction func btnIncrement(_ sender: UIButton)
{
if let d = self.delegate {
d.didTapOnIncrement(cell: self)
}
}
@IBAction func btnDecrement(_ sender: UIButton)
{
if let d = self.delegate {
d.didTapOnDecrement(cell: self)
}
}
}
protocol ProductCollectionViewCellDelegate: NSObjectProtocol {
func didTapOnIncrement(cell: ProductCollectionViewCell)
func didTapOnDecrement(cell: ProductCollectionViewCell)
}
Now in you cellForItemAt method, add this line -\
cell.delegate = self
Now confirm that delegate confirms the protocols. In this example, I suppose it is your viewController.
extension ViewController: ProductCollectionViewCellDelegate {
func didTapOnIncrement(cell: ProductCollectionViewCell) {
//let indexPath = self.tableView.indexPath(for: cell)
//You have the cell's instance here. You can also get the indexPath by delegate method.
//You can add the increment-decrement logic here.
}
func didTapOnDecrement(cell: ProductCollectionViewCell) {
//let indexPath = self.tableView.indexPath(for: cell)
//You have the cell's instance here. You can also get the indexPath by delegate method.
//You can add the increment-decrement logic here.
}
}
Upvotes: 2
Reputation: 1105
Try this simple n sober
add this code in your viewcontroller
@IBAction func onBtnPlusClick(_ sender : UIButton) {
if let cell = sender.superview?.superview as? ProductCollectionViewCell {
let indexPath = yourCollectionViewOutlet.indexPath(for: cell)
//Do whatever you want or update your data model values
yourCollectionViewOutlet.reloadData()
}
}
@IBAction func onBtnMinusClick(_ sender : UIButton) {
if let cell = sender.superview?.superview as? ProductCollectionViewCell {
let indexPath = yourCollectionViewOutlet.indexPath(for: cell)
//Do whatever you want or update your data model values
yourCollectionViewOutlet.reloadData()
}
}
In your cellForItemAt
add target to button
btnPlus.addTarget(self, action: #selector(self. onBtnPlusClick(_:)), for: .touchUpInside)
btnMinus.addTarget(self, action: #selector(self. onBtnPlusClick(_:)), for: .touchUpInside)
Add two button outlets in ProductCollectionViewCell
class
@IBOutlet var btnPlus : UIButton!
@IBOutlet var btnMinus : UIButton!
That's it, hope this help
Upvotes: 0
Reputation: 528
i say, always configure your cell data inside the cell class
import UIKit
class ProductCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var addOrMinusLabel: UILabel!
@IBOutlet weak var ProdPrice: UILabel!
@IBOutlet weak var ProdtOrgPrice: UILabel!
@IBOutlet weak var ProductImage: UIImageView!
@IBOutlet weak var ProdName: UILabel!
@IBOutlet weak var ProdWeight: UILabel!
var count = 1 {
didSet{
self.addOrMinusLabel.text = "\(count)"
}
}
func configureData(count: Int) {
self.count = count
}
@IBAction func subtract(_ sender: UIButton) {
self.count -= 1
}
@IBAction func add(_ sender: UIButton) {
self.count += 1
}
}
and in your view controller
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if(collectionView == ProductCollectionView){
let Productcell = self.ProductCollectionView.dequeueReusableCell(withReuseIdentifier:"ProductCollectionViewCell", for: indexPath) as! ProductCollectionViewCell
Productcell.configureData(count: (bestOfferProductCount[indexPath.row]))
// do try to configure these below labels also within cell class
Productcell.ProdName.text = bestOfferProductName[indexPath.row]
Productcell.ProdPrice.text = bestOfferProductPrice[indexPath.row]
Productcell.ProdtOrgPrice.text = bestOfferProductOriginalPrice[indexPath.row]
Productcell.ProdWeight.text = bestOfferProductWeight[indexPath.row]+" "+bestOfferProductUnit[indexPath.row]
Productcell.ProductImage.setImageFromURl(stringImageUrl: bestOfferProductImage[indexPath.row])
return Productcell
}
}
Upvotes: 2
Reputation: 2748
There are multiple ways to approach this.
When you're dequeuing a Cell, you have to removeAllObservers, then AddTarget from cell to your ViewController for tapEvents of Plus and Minus sign with sender. In your callee method, you have to fetch it's superView (until you reach the collectionViewCell view) and then ask from UICollectoinView for itemIndex for that cell, and update your view and cell and model accordingly.
You can define two closures one for plus and one for minus in your Cell and instead of adding Target to your viewController, add targets to your cell and call corresponding closures and each time you're trying to return a Cell, set those closures and act on them accordingly.
class CustomCell: UICollectionCell {
var plusAction: (() -> Void)?
var minusAction: (() -> Void)?
@IBOutlet var counterLabel: UILabel!
@IBAction plusTapped() {
plusAction?()
}
@IBAction minusTapped() {
minusAction?()
}
}
and in your cellDequeue method:
cellForItemAtIndexPath(/*...other parameters...*/) -> UICollectionCell {
let cell = collectionView.dequeueCell(/*...other parameters...*/) as! CustomCell
// other customizations
// weak allocation in closure might not be needed here since closure reference is nullable on the other end, but i wrote it just in-case.
cell.plusAction = { [weak weakCell = cell] in
let counter = 0 // i said 0 for ex, You actually have to have them stored somewhere (even initial zeros) and fetch the actual value for this indexPath
let newCounter = counter + 1
// update your Model with newCounter
weakCell?.counterLabel.text = "\(newCounter)"
}
cell.minusAction = { [weak weakCell = cell] in
let counter = 0 // i said 0 for ex, You actually have to have them stored somewhere (even initial zeros) and fetch the actual value for this indexPath
let newCounter = counter - 1
// update your Model with newCounter
weakCell?.counterLabel.text = "\(newCounter)"
}
}
Upvotes: 1