saumya ranjan Gangwar
saumya ranjan Gangwar

Reputation: 73

How to update a label text with button inside a collection view in swift 4

I have a collection view inside a table view. There are two plus minus buttons in collection view cell. Now i have to update a label on the plus minus buttons action which is outside of table view. Thanks in advance.

enter image description here

I have to update a Slot: (label) by clicking on plus minus button.

I tried something like this with the delegate protocol.

I declare a delegate in my collection view class.

 protocol SlotsCollectionViewCellDelegate: NSObjectProtocol {
func didTapOnIncrement(Int: Int)
func didTapOnDecrement(Int: Int)

}

//after that,

 var delegate: SlotsCollectionViewCellDelegate?


 @IBAction func plusBtnAction(_ sender: Any) {
     self.delegate?.didTapOnIncrement(Int: cartCount)
  }

   @IBAction func minusBtnAction(_ sender: Any) {
     delegate?.didTapOnDecrement(cell: self)
   }

And in my Main View Controller

extension MainViewController: SlotsCollectionViewCellDelegate {

func didTapOnIncrement(Int: Int) {
       cartSlot_lbl.text = Int.description
     }

     func didTapOnDecrement(Int: Int) {
         cartSlot_lbl.text = Int.description
     }

}

Upvotes: 0

Views: 953

Answers (2)

Pietro Messineo
Pietro Messineo

Reputation: 837

If I understood correctly, each time you push + or - you want to update slot label. In my opinion the easiest and fastest way to achieve this it's using NotificationCenter.default.post

In your collection view cell on button action write:

NotificationCenter.default.post(name: Notification.Name("postAction"), object: numberToIncreaseOrDecrease)

In your MainViewController where you have the slot label, add this code in view did load:

NotificationCenter.default.addObserver(self, selector: #selector(updateSlotValue(_:)), name: NSNotification.Name("postAction"), object: nil)

And out from the view did load add this function:

 @objc func updateSlotValue(_ notification: Notification) {
    let value = notification.object as! Int
    cartSlot_lbl.text.text = value
}

Upvotes: 1

emmics
emmics

Reputation: 1063

I think delegates are the right choice for that. If it didn't work, please explain why and show some code, you probably forgot to set a delegate reference.

Anyway, here's some more thoughts:

  • You could use a Reactive Pattern, so that you create a Relay to store your current values, manipulate them by providing input (times etc.) and subscribe to them from the Class where the "Spot:" Label is implemented. Whenever your model changes, your Spot Label will also be changed.

  • You could also implement something using Notifications. Basically speaking, the difference to using a reactive pattern is not that big, you simply have to care about the "notify" part yourself. Assuming you have something like a Singleton Pattern applied where you store your entire State (selected dates/times, slots etc.), you could do that like this:

extension Notification.Name {
    static let modelDidChange = Notification.Name("modelDidChange")
}
// where your model lies
struct YourModel {
    var slots: Int = 0

    static var singletonInstance: YourModel = YourModel() {
        // use the didSet block to react to changes made to the model
        didSet {
            // send a notification so all subscriber know something has changed
            NotificationCenter.default.post(.modelDidChange)
        }
    }
}

class YourViewControllerWhereTheLabelIs: UIViewController {
    // ...
    var slotLabel: UILabel?

    // ...
    init() {
        // wherever you initialize your viewcontroller,
        // you could also do it in viewWillAppear
        // subscribe to the notification to react to changes
        NotificationCenter.default.addObserver(self, selector: #selector(modelDidChange), name: .modelDidChange, object: nil)
    }

    deinit {
        // just don't forget to unsubscribe
        NotificationCenter.default.removeObserver(self)
    }

    @objc func modelDidChange() {
        // update your label here, this is called whenever YourModel.singletonInstance is changed
        self.slotLabel?.text = YourModel.singletonInstance.slots
    }
}


Hope that helps you or gives you an idea. If I can be of more help just let me know.

Upvotes: 1

Related Questions