从 UITableViewCell 的 accessoryView 中的自定义按钮获取索引路径

Get the indexpath from custom button in accessoryView of a UITableViewCell

我有一个 UISearchController 和一个单独的 UITableViewController 作为它的 searchResultsController

class SearchResultsViewController: UITableViewController {

    var fruits: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.tableFooterView = UIView(frame: .zero)
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
    }

    @objc func addFruit(_ sender: UIButton) {
        let point = tableView.convert(sender.bounds.origin, to: sender)
        let indexPath = tableView.indexPathForRow(at: point)
        print(indexPath?.row)
    }

    // MARK: - Table view data source
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return fruits.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = fruits[indexPath.row]
        cell.selectionStyle = .none

        let addButton = UIButton(type: .custom)
        addButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
        addButton.setImage(UIImage(named: "add"), for: .normal)
        addButton.contentMode = .scaleAspectFit
        addButton.addTarget(self, action: #selector(addFruit(_:)), for: .touchUpInside)
        addButton.sizeToFit()
        cell.accessoryView =  addButton

        return cell
    }

}

我需要在显示搜索结果的单元格中显示自定义按钮。所以我添加了一个 UIButton 作为单元格的 accessoryView。它看起来和工作正常。

现在我需要在用户点击此按钮时获取单元格的 indexPath

我正在尝试如下所示获取它。

@objc func addFruit(_ sender: UIButton) {
    let point = tableView.convert(sender.bounds.origin, to: sender)
    let indexPath = tableView.indexPathForRow(at: point)
}

但它会为每个单元格返回 nil

有没有其他方法可以通过点击自定义按钮获得 indexPath?我在这里也添加了一个demo project

创建一个名为 SOButton 的自定义 class 并向其添加 IndexPath 类型的变量。使用此 class 进行添加按钮初始化。

//Your class will look like - 

class SOButton: UIButton {
   var indexPath: IndexPath?
}

//Your action will look like -

@objc func addFruit(_ sender: SOButton) {
     print(sender?.indexPath.row)
}

//And in your cellForRow add

let addButton = SOButton(type: .custom)
addButton.indexPath = indexPath

希望对您有所帮助:)

 let buttonPosition =  sender.convert(CGPoint.zero, to: self.tableView)
 let currentIndexPath = self.tableView.indexPathForRow(at: buttonPosition)

试试这个对我有用:)

我建议使用这种简单的解决方案:将 indexPath.row 添加到按钮标签:

let addButton = UIButton(type: .custom)
addButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
addButton.tag = indexPath.row

在按钮操作中:

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

请更新您的代码。您在转换函数中传递了 UIButton 发送器,请将 tableView 传递给它们

func getIndexPathByCgPoint(_ sender: UIButton) -> IndexPath? {
    let point = sender.convert(sender.bounds.origin, to: tableview)
    guard let indexPath = tableview.indexPathForRow(at: point) else {
        return nil
    }
    return indexPath
}

但在 header 部分的情况下 return 无。