Swift - 在TableViewCell中获取父TableView(附:获取任意类型的父View)
一、在TableViewCell里获取对应的TableView
有时我们需要在自定义的单元格(tableViewCell)中获取其所在的表格(tableView)对象。除了可以从外部把 tableView 传入到 cell 中去外,还可以通过循环遍历 cell 的 superview 来得到其所在的父 tableView。
1,扩展UITableViewCell
为方便使用,这里对 UITableViewCell 进行扩展,添加个方法用来获取其所在的 tableView。
extension UITableViewCell { //返回cell所在的UITableView func superTableView() -> UITableView? { for view in sequence(first: self.superview, next: { $0?.superview }) { if let tableView = view as? UITableView { return tableView } } return nil } }
2,使用样例
我们在每个单元格尾部添加一个按钮,点击后打印出这个按钮所在单元格的 indexPath。(先得到 tableView,再根据 tableView 获取到当前 cell 所在的 indexPath)
(1)效果图
import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { var tableView:UITableView? override func loadView() { super.loadView() } override func viewDidLoad() { super.viewDidLoad() //创建表视图 self.tableView = UITableView(frame: self.view.frame, style:.plain) self.tableView!.delegate = self self.tableView!.dataSource = self self.tableView!.allowsSelection = false //创建一个重用的单元格 self.tableView!.register(MyTableCell.self, forCellReuseIdentifier: "tableCell") self.view.addSubview(self.tableView!) } //在本例中,只有一个分区 func numberOfSections(in tableView: UITableView) -> Int { return 1 } //返回表格行数(也就是返回控件数) 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) as! MyTableCell cell.textLabel?.text = "条目\(indexPath.row)" return cell } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } //单元格类 class MyTableCell: UITableViewCell { var button:UIButton! //初始化 override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) button = UIButton(frame:CGRect(x:0, y:0, width:40, height:25)) button.setTitle("点击", for:.normal) //普通状态下的文字 button.backgroundColor = UIColor.orange button.layer.cornerRadius = 5 button.titleLabel?.font = UIFont.systemFont(ofSize: 13) //按钮点击 button.addTarget(self, action:#selector(tapped(_:)), for:.touchUpInside) self.addSubview(button) } //布局 override func layoutSubviews() { super.layoutSubviews() button.center = CGPoint(x: bounds.size.width - 35, y: bounds.midY) } //按钮点击事件响应 func tapped(_ button:UIButton){ let tableView = superTableView() let indexPath = tableView?.indexPath(for: self) print("indexPath:\(indexPath!)") } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
二、获取任意类型的父View
我们可以对上面的方法做个改进,通过扩展 UIView,让我们可以获得任意视图对象(View)所在的指定类型的父视图。
1,扩展View
这里对 UIView 进行扩展,根据传入的类型,循环遍历获取该类型的父 View。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 } }
2,使用样例
这里对上面样例代码做个修改,之前我们在单元格中这么得到该 cell 所在的 tableView:
let tableView = superTableView()
现在改成这样:
let tableView = superView(of: UITableView.self)
这种方式,如果没有显示的cell,也是获取不了的
楼主能具体说下吗?我现在tableview的cell中有UITextField,可以动态增删cell,页面中有一个保存按钮,点击保存想获取所有cell中控件的值,该怎么操作。visibleCells只能获取显示的cell,不能获取全部。
请问楼主怎么获取tableView所有的cell