Hi I have a custom UITableViewCell with three buttons to handle a shopping cart function, Plus,Minus and Delete button and I need to know which cell has been touched.
I've already tried to use the "tag solution" but it isn't working due to the lifecycle of the cells.
Can anyone please help me find a solution?
Thanks in advance
add an 'indexPath` property to the custom table cell. initialize it in cellForRowAtIndexPath. move the tap handler from the view controller to the cell implementation. use the delegation pattern to notify the view controller about the tap event, passing the index path.
func tableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath) Tells the delegate the table view is about to draw a cell for a particular row. func tableView(UITableView, indentationLevelForRowAt: IndexPath) -> Int. Asks the delegate to return the level of indentation for a row in a given section.
I was resolving this using a cell delegate method within UITableViewCell's subclass.
Quick overview:
1) Create a protocol
protocol YourCellDelegate : class { func didPressButton(_ tag: Int) }
2) Subclass your UITableViewCell
(if you haven't done so):
class YourCell : UITableViewCell { var cellDelegate: YourCellDelegate? @IBOutlet weak var btn: UIButton! // connect the button from your cell with this method @IBAction func buttonPressed(_ sender: UIButton) { cellDelegate?.didPressButton(sender.tag) } ... }
3) Let your view controller conform to YourCellDelegate
protocol that was implemented above.
class YourViewController: ..., YourCellDelegate { ... }
4) Set a delegate, after the cell has been defined (for reusing).
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! YourCell cell.cellDelegate = self cell.btn.tag = indexPath.row
5) In the same controller (where is your implemented UITableView delegate/datasource), put a method from YourCellDelegate
protocol.
func didPressButton(_ tag: Int) { print("I have pressed a button with a tag: \(tag)") }
Now, your solution is not tag / number dependent. You can add as many buttons as you want, so you are ready to get response via delegate regardless how many buttons you want to install.
This protocol-delegate solution is preferred in iOS logic and it can be used for other elements in table cell, like UISwitch
, UIStepper
, and so on.
swift 4.2
You can also use closures instead of delegates
1) In your UITableViewCell :
class ExampleCell: UITableViewCell {
//create your closure here
var buttonPressed : (() -> ()) = {}
@IBAction func buttonAction(_ sender: UIButton) {
//Call your closure here
buttonPressed()
}
}
2) In your ViewController
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ExampleCell", for: indexPath) as! ExampleCell
cell.buttonPressed = {
//Code
}
return cell
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With