ios 如何在 Swift 中的 UITableViewCell 上添加带有单击事件的按钮?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30105189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:56:19  来源:igfitidea点击:

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

iosuitableviewswift

提问by Kemal Müderriso?lu

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

在我的主页中,我为 UITableViewCell 创建了一个 xib 文件。我正在从那个 xib 文件加载单元格并且它工作正常。

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.

这是我的 .swift 代码后面的 xib 文件。

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.

当我单击 Cell 内的 fav 按钮时。例如,我想将时间标签文本更改为任何内容。

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

当我点击 fav 按钮时,事件将转到 SepetCell.swift favoriteClicked(sender: UIButton) 函数。

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

因此,如果我尝试调用: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.

但是 sepetTable 在它消失时为零。我认为这是因为当我调用这个 SepetViewController().favorite(sender.tag) 函数时。它首先创建 SepetViewController 类。因此,由于未设置对象,它变得空了。

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

我怎样才能到达那个 sepetTable 或者什么是解决这个问题的最佳方法。

Thanks.

谢谢。

回答by raf

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

解决这个问题的流行模式是闭包和委托。如果你想使用闭包,你可以这样做:

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

then

然后

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

then in your tableview delegate:

然后在您的 tableview 委托中:

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 the delegate pattern:

一种流行的替代方法是使用委托模式:

    protocol MyCellDelegate: class {
        func didTapButtonInCell(_ cell: MyCell)
    }

    final class MyCell: UITableViewCell {
        weak var delegate: MyCellDelegate?

then

然后

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

.. Now in your view controller:

.. 现在在您的视图控制器中:

then in your tableview delegate:

然后在您的 tableview 委托中:

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

    let cell = tableView.dequeueReusableCellWithIdentifier("MyCellIdentifier") as? MyCell
    cell?.delegate = self

And add conformance to the protocol like this:

并添加对协议的一致性,如下所示:

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

Hope this helps!

希望这可以帮助!

回答by ingconti

All patterns above are fine. my two cents, in case You add by code(for example multiple different cells and so on..) there is a FAR simple solution.

上面的所有图案都很好。我的两分钱,如果您通过代码添加(例如多个不同的单元格等等),有一个简单的解决方案。

As buttons allow to specify a "target" You can pass directly the controller AND action to cell/button when setting it.

由于按钮允许指定“目标”,您可以在设置时直接将控制器和操作传递给单元格/按钮。

In controller:

在控制器中:

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

...

...

in custom cell with button:

在带有按钮的自定义单元格中:

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

}

回答by Mark Gerrior

2 am answer: You're over thinking this. Create a custom TableViewCell class; set the prototype cell class to your new custom class; and then create an IBAction.

凌晨 2 点回答:你想多了。创建自定义 TableViewCell 类;将原型单元类设置为您的新自定义类;然后创建一个IBAction。