Kemal Müderriso─člu Kemal Müderriso─člu - 7 months ago 87
Swift Question

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

In my main page, I created a xib file for UITableViewCell. I'm loading the cell from that xib file and its working fine.

Inside of the cell I have some labels and buttons. I'm aiming to change the label by clicking to the button on the cell.

My Code likes 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
}
}


This is my xib files behind codes as .swift.

The codes in the main page likes 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 fav button inside of the Cell. I wanted to change times label text to anything for example.

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

So if i try to call:
SepetViewController().favorite(sender.tag)

It will go inside of the

func favorite(tag: Int) {

sepetTable.reloadData()

}


but sepetTable is nil when it is gone there. I think it is because of when I call this SepetViewController().favorite(sender.tag) function. It firstly creates SepetViewController class. So because of object is not setted it is getting null.

How can I reach that sepetTable or what is the best way to solve this issue.

Thanks.

raf raf
Answer

I would define a closure in the Cell class:

class SepetCell: UITableViewCell{
    var onButtonTapped : (() -> Void)? = nil

... then...

    @IBAction func favoriteClicked(sender: UIButton) {
        println(sender.tag)
        println(times.text)
        if let onButtonTapped = self.onButtonTapped {
           onButtonTapped()
        }
   }

then in your tableview delegate:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) - > UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("productCell") as ? SepetCell
    cell.onButtonTapped = {
       //Do whatever you want to do when the button is tapped here
    }

Hope this helps!