Reputation: 164
I'm trying to detect button tap in a UITableViewCell
which is in a UICollectionViewCell
.
UICollectionView
's delegate and dataSource is my ViewController
. There is one UITableView
in every UICollectionViewCell
. And the UITableViewCell
's delegate and dataSource is the UICollectionViewCell
.
I need to detect button taps in the ViewController
.
ViewController
@IBOutlet collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
}
UICollectionView
@IBOutlet tableView: UITableView!
override func awakeFromNib() {
super.awakeFromNib()
tableView.delegate = self
tableView.dataSource = self
}
UITableViewCell
@IBAction func buttonTapped(_ sender: CustomButton) {
// Detect Button Tap in ViewController
}
Upvotes: 2
Views: 1781
Reputation: 422
You could write your own delegate for that.
protocol ButtonDelegate: class {
func buttonTapped(_ button: UIButton)
}
Then, implement it in your ViewController
and do whatever you want to happen when the button gets tapped.
In your UICollectionView
and your UITableViewCell
, add a property:
weak var buttonDelegate: ButtonDelegate?
And then, modify your UITableViewCell
:
@IBAction func buttonTapped(_ sender: CustomButton) {
buttonDelegate?.buttonTapped(sender)
}
In the ViewController
you have to set the delegate on the UICollectionView
:
collectionView.buttonDelegate = self
At last, in your cellForRowAt
method in your UICollectionView
, set the buttonDelegate
property of the UITableViewCell
to the buttonDelegate
of the UICollectionView
, which is your ViewController
:
cell.buttonDelegate = buttonDelegate
Upvotes: 2
Reputation: 11140
I would suggest you to use delegate pattern.
So you need one protocol for table view cell and one for collection view cell
protocol TableCellDelegate: class {
func buttonPressed(_ sender: CustomButton)
}
protocol CollectionCellDelegate: class {
func buttonInTableCellPressed(_ sender: CustomButton)
}
now create delegate
variables for cell subclasses
class TableCell: ... {
weak var delegate: TableCellDelegate?
}
class CollectionCell: ... {
weak var delegate: CollectionCellDelegate?
}
continue with implementing TableCellDelegate
to CollectionView
and call method on cell's delegate inside table cell delegate's method
extension CollectionCell: TableCellDelegate {
func buttonPressed(_ sender: CustomButton) {
delegate?.buttonInTableCellPressed(sender)
}
}
next implement CollectionCellDelegate
to your view controller
extension ViewController: CollectionCellDelegate {
func buttonInTableCellPressed(_ sender: CustomButton) {
... // this is called when button in table view cell is pressed
}
}
Now, don't forget to set delegate of collection cell inside cellForItemAt
in ViewController
and delegate of table cell inside cellForRowAt
in CollectionCell
class ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
...
cell.delegate = self
...
}
}
class CollectionCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
cell.delegate = self
...
}
}
Now, finally, call method on delegate inside table cell when button is pressed
@IBAction func buttonTapped(_ sender: CustomButton) {
delegate?.buttonPressed(sender)
}
Upvotes: 3