How to add a button with a click event in a UITableViewCell in Swift?

On my main page, I created an xib file for a UITableViewCell. I load a cell from this xib file and its performance.

Inside the cell, I have several labels and buttons. I am trying to change a shortcut by clicking on a button in a cell.

My code is like below

import UIKit class SepetCell: UITableViewCell{ @IBOutlet var barcode: UILabel! @IBOutlet var name: UILabel! @IBOutlet var fav: UIButton! @IBOutlet var strep: UIStepper! @IBOutlet var times: UILabel! @IBAction func favoriteClicked(sender: UIButton) { println(sender.tag) println(times.text) SepetViewController().favorite(sender.tag) } override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } } 

These are my xib files for codes like .swift.

The codes on the main page will like it below:

  import UIKit import CoreData class SepetViewController: UIViewController, UITextFieldDelegate, UITableViewDataSource, UITableViewDelegate { @ IBOutlet var sepetTable: UITableView! var barcodes: [CART] = [] let managedObjectContext = (UIApplication.sharedApplication().delegate as!AppDelegate).managedObjectContext override func viewWillAppear(animated: Bool) { if let moc = self.managedObjectContext { var nib = UINib(nibName: "SepetTableCell", bundle: nil) self.sepetTable.registerNib(nib, forCellReuseIdentifier: "productCell") } fetchLog() sepetTable.reloadData() } func fetchLog() { if let moc = self.managedObjectContext { barcodes = CART.getElements(moc); } } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) - > Int { return self.barcodes.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) - > UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("productCell") as ? SepetCell if cell == nil { println("cell nil") } let product: CART product = barcodes[indexPath.row] cell!.barcode ? .text = product.barcode cell!.name ? .text = product.name cell!.fav.tag = indexPath.row return cell! } func favorite(tag: Int) { } } 

When I clicked the fav button inside the cell. I would like to change the label text to anything, for example.

When I clicked the fav button, the event will go to the SepetCell.swift favoriteClicked function (sender: UIButton).

So, if I try to call: SepetViewController (). Favorite (sender.tag)

He will go inside

 func favorite(tag: Int) { sepetTable.reloadData() } 

but sepetTable is zero when it is gone. I think this is because I call this function SepetViewController (). Favorite (sender.tag). First, it creates the SepetViewController class. Therefore, due to the fact that the object is not installed, it gets null.

How can I contact this sepetTable or how best to solve this problem.

Thanks.

+9
source share
2 answers

Popular circuits for solving this problem are closures and delegates. If you want to use closures, you should do something like this:

 final class MyCell: UITableViewCell { var actionBlock: (() -> Void)? = nil 

then

  @IBAction func didTapButton(sender: UIButton) { actionBlock?() } 

then in your table view the delegate:

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) - > UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("MyCellIdentifier") as? MyCell cell?.actionBlock = { //Do whatever you want to do when the button is tapped here } 

A popular alternative is to use a delegate template:

  protocol MyCellDelegate: class { didTapButtonInCell(_ cell: MyCell) } final class MyCell: UITableViewCell { weak delegate: MyCellDelegate? 

then

  @IBAction func didTapButton(sender: UIButton) { delegate?.didTapButtonInCell(self) } 

.. Now, in your opinion, the controller:

then in your table view the delegate:

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) - > UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("MyCellIdentifier") as? MyCell cell?.delegate = self 

And add protocol compliance like this:

 extension MyViewController: MyCellDelegate { didTapButtonInCell(_ cell: MyCell) { //Do whatever you want to do when the button is tapped here } } 

Hope this helps!

+43
source

All of the above patterns are in order . my two cents, in case you add by code (for example, several different cells, etc.), there is a simple FAR solution.

Since the buttons allow you to specify the "target", you can directly transfer the action of the controller AND to the cell / button when it is installed.

In the controller:

 let selector = #selector(self.myBtnAction) setupCellWith(target: self, selector: selector) 

...

in a custom cell with a button:

 final func setupCellWith(target: Any? selector: Selector){ btn.addTarget(target, action: selector, for: .touchUpInside) } 
0
source

Source: https://habr.com/ru/post/986759/


All Articles