UITableViewCell带动作的按钮

时间:2016-10-09 18:30:37

标签: ios swift uitableview uibutton swift3

您好我有一个带有三个按钮的自定义UITableViewCell来处理购物车功能,Plus,Minus和Delete按钮,我需要知道哪个单元格已被触摸。

我已经尝试使用“标签解决方案”但由于电池的生命周期而无法正常工作。

有人可以帮我找一个解决方案吗?

提前致谢

7 个答案:

答案 0 :(得分:48)

我是在UITableViewCell的子类中使用单元委托方法解析它。

快速概述:

1) 创建协议

protocol YourCellDelegate : class {
    func didPressButton(_ tag: Int)
}

2) 子类您的 UITableViewCell (如果您还没有这样做):

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) 您的观点控制器符合上面实施的YourCellDelegate协议。

class YourViewController: ..., YourCellDelegate {  ... }

4) 在定义单元格后设置委托(重复使用)。

let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! YourCell
cell.cellDelegate = self
cell.btn.tag = indexPath.row

5)在同一个控制器中(您实现的UITableView委托/数据源),YourCellDelegate协议中添加方法。

func didPressButton(_ tag: Int) {
     print("I have pressed a button with a tag: \(tag)")
}

现在,您的解决方案不依赖于标签/数字。您可以根据需要添加任意数量的按钮,因此无论您要安装多少个按钮,都可以通过委托获得响应。

此协议委托解决方案在iOS逻辑中是首选,它可用于表格单元格中的其他元素,如UISwitchUIStepper等。

答案 1 :(得分:13)

在IBOutlets私有化后,我遇到了同样的问题,社区广泛建议。

这是我的解决方案:

<在您的手机类>

protocol YourCellDelegate: class {
    func didTapButton(_ sender: UIButton)
}

class YourCell: UITableViewCell {

    weak var delegate: YourCellDelegate?

    @IBAction func buttonTapped(_ sender: UIButton) {
        delegate?.didTapButton(sender)
    }
}

<在您的ViewController>

class ViewController: UIViewController, YourCellDelegate {

    func didTapButton(_ sender: UIButton) {
        if let indexPath = getCurrentCellIndexPath(sender) {
            item = items[indexPath.row]
        }
    }

    func getCurrentCellIndexPath(_ sender: UIButton) -> IndexPath? {
        let buttonPosition = sender.convert(CGPoint.zero, to: tableView)
        if let indexPath: IndexPath = tableView.indexPathForRow(at: buttonPosition) {
            return indexPath
        }
        return nil
    }
}

答案 2 :(得分:3)

您还可以使用tableViewCell视图的层次结构获取选定的按钮索引。

使用以下步骤:

  1. 将选择器添加到tableview的cellForRowAtIndexpath:

    btn?.addTarget(self, action:#selector(buttonPressed(_:)), for:.touchUpInside)
    
  2. 2。使用以下方法获取indexPath:

    func buttonPressed(_ sender: AnyObject) {
            let button = sender as? UIButton
            let cell = button?.superview?.superview as? UITableViewCell
            let indexPath = tblview.indexPath(for: cell!)
            print(indexPath?.row)
        }
    

答案 3 :(得分:3)

SWIFT 4。*

它也可以按照以下方式完成,不需要太多编码和委托,简单易用。

将以下代码放在cellForItemAt UICollectionViewcellForRowAt UITableView

cell.btn.tag = indexPath.row
cell.btn.addTarget(self, action: #selector(buttonSelected), for: .touchUpInside)

你的方法将是

@objc func buttonSelected(sender: UIButton){
    print(sender.tag)
}

多数人。

答案 4 :(得分:2)

迅速4.2

您也可以使用闭包代替委托

1)在您的UITableViewCell中:

 class ExampleCell: UITableViewCell {
    //create your closure here  
         var buttonPressed : (() -> ()) = {}

        @IBAction func buttonAction(_ sender: UIButton) {
    //Call your closure here 
            buttonPressed()
        }
    }

2)在您的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 
  }
}

答案 5 :(得分:1)

Tableview单元格中的

UIButton。在Swift 4.2中以编程方式创建动作方法

{{1}}

答案 6 :(得分:0)

@pedrouan很棒,除了使用按钮的tag选项。在许多情况下,当您在tableViewCell上设置按钮时,这些按钮将修改tableView dataSource。(例如InsertRow,DeleteRow)。

但即使新单元格为inserteddeleted,按钮标记也不会更新。因此,最好将cell本身作为参数传递,而不是将按钮的tag传递给参数。

这是我实现这个目标的例子。

您的ExampleCell

protocol ExampleCellDelegate: class {
    func didTapButton(cell: ExampleCell)
}

class ExampleCell: UITableViewCell {

    weak var cellDelegate: ExampleCellDelegate?

    @IBAction func btnTapped(_ sender: UIButton) {
        cellDelegate?.didTapButton(cell: self)
    }
}

您的ViewController

class ViewController: ExampleCellDelegate {
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "ExampleCell", for: indexPath) as? ExampleCell {

            cell.cellDelegate = self
            return cell
        }
        return UITableViewCell()
    }

    func didTapButton(cell: ExampleCell) {
        if let indexPath = tableView.indexPath(for: cell) {
            // do Something
        }
    }
}