Swift - 在单元格里的按钮点击事件中获取对应的cell以及indexPath
有时我们需要在 tableView 的自定义单元格中添加一些按钮,并在按钮点击方法中进行一些业务逻辑。比如下面样例,在每个单元格尾部都有一个加号按钮,点击后会把该单元格的数字加到总数上,并显示在标题栏中。

整个页面以及单元格自定义是在 storyboard 中实现的,同时将 button 的点击事件绑定到 VC 中。这就要求我们在点击事件中要先得到按钮所在的 cell,再获取这个 cell 里的文本标签,最后将标签内容转换成数字与总数相加。

1,在点击事件中获取对应的cell
我们添加一个 superUITableViewCell 方法通过遍历循环 button 的 superview 来获取其对应的 cell。这个原理和我之前写的文章类似:Swift - 在TableViewCell中获取父TableView(附:获取任意类型的父View)
import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { @IBOutlet weak var tableView: UITableView! //总数 var sum = 0 override func loadView() { super.loadView() self.title = "总数:\(sum)" } override func viewDidLoad() { super.viewDidLoad() self.tableView.delegate = self self.tableView.dataSource = self self.tableView.allowsSelection = false } //返回表格行数(也就是返回控件数) func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 20 } //创建各单元显示内容(创建参数indexPath指定的单元) func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { //创建一个重用的单元格 let cell = tableView .dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) let label = cell.viewWithTag(1) as! UILabel label.text = "\(indexPath.row)" return cell } //单元格中的按钮点击 @IBAction func tapAddButton(_ sender: AnyObject) { let btn = sender as! UIButton let cell = superUITableViewCell(of: btn)! let label = cell.viewWithTag(1) as! UILabel sum = sum + (label.text! as NSString).integerValue self.title = "总数:\(sum)" } //返回button所在的UITableViewCell func superUITableViewCell(of: UIButton) -> UITableViewCell? { for view in sequence(first: of.superview, next: { $0?.superview }) { if let cell = view as? UITableViewCell { return cell } } return nil } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }
2,功能改进
(1)我们可以通过扩展 UIView,让我们可以获得任意视图对象(View)所在的指定类型的父视图。
(2)在 button 点击事件中可以这么获取到对应的 cell:
extension UIView { //返回该view所在的父view func superView<T: UIView>(of: T.Type) -> T? { for view in sequence(first: self.superview, next: { $0?.superview }) { if let father = view as? T { return father } } return nil } }
//单元格中的按钮点击 @IBAction func tapAddButton(_ sender: AnyObject) { let btn = sender as! UIButton let cell = btn.superView(of: UITableViewCell.self)! let label = cell.viewWithTag(1) as! UILabel sum = sum + (label.text! as NSString).integerValue self.title = "总数:\(sum)" }
3,在点击事件中获取对应的indexPath
获取到 cell 后,通过 tableView 的 indexPath(for:) 方法即可得到对应的 indexPath。
//单元格中的按钮点击 @IBAction func tapAddButton(_ sender: AnyObject) { let btn = sender as! UIButton let cell = btn.superView(of: UITableViewCell.self)! let indexPath = tableView.indexPath(for: cell) print("indexPath:\(indexPath!)") }源码下载:
