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!)")
}
源码下载: