You have a few possibilities here. One of them and the easiest, would be using tags.
To you give a complete solution, you would first need to add a tag to your button in the cellForRowAtIndexPath
method.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: yourReuseIdentifier, for: indexPath) as! YourCustomCell
// Set your button tag to be equal to the indexPath.row:
cell.button.tag = indexPath.row
// Add a target to your button making sure that you return the sender like so:
cell.button.addTarget(self, action: #selector(handleButtonTapped(sender:)), for: .touchUpInside)
}
And now this is how it would look like inside your handlerButtonTapped()
method :
func handleButtonTapped(sender: UIButton) {
// Now you can easily access the sender's tag, (which is equal to the indexPath.row of the tapped button).
// Access the selected cell's index path using the sender's tag like so :
let selectedIndex = IndexPath(row: sender.tag, section: 0)
// And finally do whatever you need using this index :
tableView.selectRow(at: selectedIndex, animated: true, scrollPosition: .none)
// Now if you need to access the selected cell instead of just the index path, you could easily do so by using the table view's cellForRow method
let selectedCell = tableView.cellForRow(at: selectedIndex) as! YourCustomCell
}
Another possibility, would be using closures.
Create a subclass of UITableViewCell :
class CustomTableCell: UITableViewCell {
var shouldSelectRow: ((CustomTableCell) -> Void)?
// MARK: User Interaction
@IBAction func handleDidTapButton(_ sender: UIButton) {
// Call your closure whenever the user taps on the button:
shouldSelectRow?(self)
}
}
Now you could set up your cellForRowAtIndexPath
method like this:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// ...
cell.shouldSelectRow = { (selectedCell) in
// Since you now know which cell got selected by the user, you can access via its index path:
let selectedIndex = self.tableView.indexPath(for: selectedCell)
// Do whatever you need using the selected cell here
self.tableView.selectRow(at: selectedIndex, animated: true, scrollPosition: .none)
}
// ...
}
Note: You could also use delegates.
And it would work as well :)