KevinVuD
KevinVuD

Reputation: 611

How do I pass button action from a nested collectionView cell?

I have a MainCollectionView used for scrolling between items, inside of one of these cells I have another collectionView with cells. In that collection view, I have a button for each cell. My question is how do I pass action from my button to my MainCollectionView when it is tapped? I did create protocol for that button in the cell but I don't know how to let MainCollectionView know when my button is tapped. I can call action from my cell class but I think it is better to run it in Model which is my MainCollectionView. Below is my button protocol.

protocol ThanhCaHotTracksCellDelegate: class {
func handleSeeAllPressed()}

weak var delegate: ThanhCaHotTracksCellDelegate?


@objc func handleSeeAllButton(){
 delegate?.handleSeeAllPressed()
}

Upvotes: 3

Views: 1468

Answers (2)

heyfrank
heyfrank

Reputation: 5647

LIke NSAdi said, you're on the right track, but the delegate pattern is a bit much overhead for just a single task like notifying about a button press.

I prefer using closures, because they're lightweight and helps to keep related code together.

Using Closures

This is what I'm always doing in UITableView. So this will work in UICollectionView too.

class MyTableViewCell: UITableViewCell {
    var myButtonTapAction: ((MyTableViewCell) -> Void)?

    @IBAction func myButtonTapped(_ sender: Any) {
        myButtonTapAction?(self)
    }
}

So when I dequeue my cell and cast it to MyTableViewCell I can set a custom action like this:

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

    cell.myButtonTapAction = { cell in
        // Put your button action here
        // With cell you have a strong reference to your cell, in case you need it
    }
}

Using direct reference

When you're dequeueing your UICollectionView cell you can obtain a reference to your button by casting the cell to your cell's custom subclass.

Then just do the following

cell.button.addTarget(self, action: #selector(didTapButton(_:)), forControlEvents: .TouchUpInside)

And outside have a function:

@objc func didTapButton(_ sender: UIButton) {
    // Handle button tap
}

Downside of this is that you have no direct access to your cell. You could use button.superview? but it's not a good idea since your view hierarchy could change...

Upvotes: 6

NSAdi
NSAdi

Reputation: 1253

You're on the right track.

Make sure MainCollectionView (or the class that contains) it implements ThanhCaHotTracksCellDelegate protocol.

Then assign the delegate as self.

Something like...

class ViewController: ThanhCaHotTracksCellDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()

        subCollectionView.delegate = self
    }
}

Upvotes: 0

Related Questions