【问题标题】:Detect UIButton from Custom UITableViewCell in Swift 3 [duplicate]从 Swift 3 中的自定义 UITableViewCell 中检测 UIButton [重复]
【发布时间】:2016-12-27 17:51:37
【问题描述】:

我有一个自定义 UITableViewCell,我在其中使用 Interface Builder 连接了我的 UIButton

@IBOutlet var myButton: UIButton!

在 UITableViewController 的单元格配置下,我有以下代码:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

var customCell = tableView.dequeueReusableCell(withIdentifier: self.MY_CELL_IDENTIFIER, for: indexPath) as! myCustomCell

// CONFIGURE OTHER CELL PARAMETERS

customCell.myButton.tag = indexPath.row

customCell.myButton.addTarget(self, action: #selector(myButtonPressed), for: UIControlEvents.touchUpInside)

return customCell

}

最后,我有

private func myButtonPressed(sender: UIButton!) {
        let row = sender.tag
        print("Button Sender row: \(row)")            
    }

此代码不起作用,除非我将函数定义更改为以下:

@objc private func myButtonPressed(sender: UIButton!) {
            let row = sender.tag
            print("Button Sender row: \(row)")

        }

有没有更好的方法在 Swift 3 中的自定义 UITableViewCell 上实现 UIButton

【问题讨论】:

  • 您是否尝试过从界面构建器创建操作?
  • 放弃私有关键字
  • @LopesFigueiredo - 我没有创建 IBAction 的原因是因为会有多行,我必须检测按钮是从哪一行按下的。
  • 每次重复使用一个单元格时,您都会为每个按钮添加目标。如果您不想在触摸按钮时多次调用 myButtonPressed 方法,则只需添加一次目标。
  • @LopesFigueiredo - 谢谢。我知道如何创建 IBAction,但是为了从行中唯一标识每个 UIButton,我尝试了上面详述的方法。

标签: ios swift xcode


【解决方案1】:

我不是使用视图tags 的忠实粉丝。取而代之的是,您可以使用viewController 的委托模式在按下按钮时收到通知。

protocol CustomCellDelegate: class {
    func customCell(_ cell: UITableViewCell, didPressButton: UIButton)
}

class CustomCell: UITableViewCell {
    // Create a delegate instance
    weak var delegate: CustomCellDelegate?

    @IBAction func handleButtonPress(sender: UIButton) { 
        self.delegate?.customCell(self, didPressButton: sender)
    }
}

class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var customCell = tableView.dequeueReusableCell(withIdentifier: "identifier", for: indexPath) as! CustomCell
        // CONFIGURE OTHER CELL PARAMETERS

        //Assign the cell's delegate to yourself
        customCell.delegate = self
        return customCell
    }
}

extension ViewController: CustomCellDelegate {
    // You get notified by the cell instance and the button when it was pressed
    func customCell(_ cell: UITableViewCell, didPressButton: UIButton) {
        // Get the indexPath
        let indexPath = tableView.indexPath(for: cell) 
    }
}

【讨论】:

    【解决方案2】:

    是的,有一种更智能、更好的方法可以做到这一点。您的方法的主要问题是,它仅在没有插入、删除或移动单元格操作发生时才有效。因为这些操作中的任何一个都可以更改为不同 indexPath 创建的单元格的 de indexPath。

    我使用的系统是这样的:

    1.- 在您的单元格类 MyCustomCell 中创建一个 IBAction(使用大写 M。它是一个类,因此请正确命名)。

    2.- 将按钮连接到该操作。

    3.- 至少使用方法声明协议 MyCustomCellDelegate

    func myCustomCellButtonAction(_ cell:MyCustomCell)
    

    并向 MyCustomCell 添加一个属性

     var delegate : MyCustomCellDelegate?    
    

    4.- 将视图控制器设置为 MyCustomCellDelegate

    在连接到按钮的MyCustomCell方法中调用委托方法:

     delegate?.myCustomCellButtonAction( self )
    

    5.- 在视图控制器中,在 cellForRowAt 方法中:

     customCell.delegate = self
    

    6.- 在视图控制器中,在 myCustomCellButtonAction 方法中:

    func myCustomCellButtonAction( _ cell: MyCustomCell ) {
        let indexPath = self.tableView.indexPathForCell( cell )
    
        // ......  continue .....
    }
    

    【讨论】:

      【解决方案3】:

      您也可以使用委托来做同样的事情。

      在你的自定义 UITableViewCell 类中直接映射按钮的 IBAction。

      在 viewcontroller 中实现委托方法,并在按钮操作中从自定义单元格调用委托方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-12
        • 2015-12-02
        • 2012-01-11
        相关资源
        最近更新 更多