前言
UITableView
是我们开发中最常见的列表,UITableView
继承自
UIScrollView``UIScrollView
可以在任意方向滑动,UITableView
只能在垂直方向滑动
UITableView
的内容由 UITableViewCell
来显示的
UITableViewCell
可以使用系统自带样式,也可以自定义
创建 UITableView
- 我们在实际开发中通常是用
延迟加载
的方式来创建,如下:
1 2 3 4 5 6
| // 懒加载:延迟加载 - 第一次使用的时候才加载 lazy var tableV: UITableView = { let tableV = UITableView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height), style: .plain) tableV.backgroundColor = UIColor.red return tableV }()
|
注:
style 有两种样式:plain
和 group
区别:
plain:
1、plain类型有多个header时,header停留(自带效果)
2、plain类型section之间没有间距
group:
1、类型有多个header时,header不停留
2、plain类型section之间有间距
1 2
| // 添加tableV到vc的view上 self.view.addSubview(self.tableV)
|
设置代理
1 2 3 4 5 6 7 8 9
| // 懒加载:延迟加载 - 第一次使用的时候才加载 lazy var tableV: UITableView = { let tableV = UITableView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height), style: .plain) tableV.backgroundColor = UIColor.red // 设置代理 tableV.delegate = self tableV.dataSource = self return tableV }()
|
可以通过 extension
去遵守代理
1 2 3
| extension ViewController: UITableViewDataSource,UITableViewDelegate { }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| extension ViewController: UITableViewDataSource,UITableViewDelegate { // 组的个数 func numberOfSections(in tableView: UITableView) -> Int { return 1 } // 每组的row数 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 10 } // 每个row的cell func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // 系统的cell let cellId = "testCellId" var cell = tableV.dequeueReusableCell(withIdentifier: cellId) if cell == nil { cell = UITableViewCell(style: .default, reuseIdentifier: cellId) } cell?.textLabel?.text = "标题" cell?.detailTextLabel?.text = "内容" cell?.imageView?.image = UIImage(named: "test") return cell! } // cell的高度 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 70 } // 选中cell执行的方法 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print(indexPath.row) } }
|
注:系统样式的cell有三种样式:default,value1,value2,subtitle
自定义cell
- 创建一个 BaseTableViewCell 基类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import UIKit
class BaseTableViewCell: UITableViewCell { // 基础 class func BaseTableViewCell(tableView:UITableView,indexPath:NSIndexPath) -> UITableViewCell{ let ID = NSStringFromClass(self); let cls = NSClassFromString(ID) as! UITableViewCell.Type; let cell = tableView.dequeueReusableCell(withIdentifier: ID) ?? cls.init(style: .default, reuseIdentifier: ID) return cell } /* 子类默认不继承父类的初始化器,实际上是通过 重写 父类的初始化器实现的,用 override 关键字 子类调用父类的初始化区,用 super */ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.prepareUI() } // UI func prepareUI() { self.contentView.backgroundColor = kColorRandom(); } // 必要初始化器:可失败 required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } // 反初始化器 deinit { print("deinit") } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import UIKit
class CustomTableViewCell: BaseTableViewCell { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.prepareUI() } override func prepareUI() { super.prepareUI(); self.contentView.backgroundColor = .white; initUI(); initConstraint(); } func initUI() { self.contentView.addSubview(bgV); } func initConstraint() { }
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
|
1 2 3
| let cell = CustomTableViewCell.BaseTableViewCell(tableView: tableView, indexPath: indexPath as NSIndexPath) return cell
|
cell 的插入和删除
1 2
| // editing: 是否开启编辑状态 animated: 是否有动画效果 setEditing(_ editing:, animated:)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| // 编辑模式:insert 添加操作、delete删除操作、none 没有任何操作 func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle { return .delete } // 执行编辑操作:调用此方法 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .insert { // 添加 dataArr.insert("\(indexPath.row)", at: indexPath.row) // 添加操作 tableView.insertRows(at: [indexPath], with: .right) }else { // 删除 dataArr.remove(at: indexPath.row) // 删除 print(dataArr) tableView.deleteRows(at: [indexPath], with: .left) } } // 修改删除的文字 func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? { return "删除" }
|
cell位置移动
1 2
| // editing: 是否开启编辑状态 animated: 是否有动画效果 setEditing(_ editing:, animated:)
|
1 2 3 4 5 6 7 8 9 10
| // 设置cell是否可移动 func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { return true } // 移动结束后调用此方法 func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { let data = dataArr[sourceIndexPath.row] dataArr.remove(at: sourceIndexPath.row) dataArr.insert(data, at: destinationIndexPath.row) }
|