简介
表格视图是一种将内容一行一行展现出来的视图,每一行称为一个Cell,iOS默认每一行只有一个Cell,Cell支持自定义。 Cell分为动态和静态,动态指在程序运行期间自动生成Cell,一般用于事先不知道Cell的具体数量时。如果是静态的Cell,在StoryBoard中可以直接拖放需要的数量到TableView上。预设的Cell可以放入一张图片,一段文字以及一个指示器(位于Cell最右边)。 集合视图UICollectionView与TableView非常相似,不同的是CollectionView支持每一行放入多个Cell,超过屏幕右边界的Cell会自动排列到下一行,在iPad设备旋转时会自动重新排列,而且支持自定义Cell布局方式(如电商项目常用的瀑布流布局)。
表格的三段对话
如果想使用TableView视图,需要将其交给一个ViewController来管理。这个ViewController需要遵循UITableViewDataSource和UITableViewDelegate协议,前者用于设置TableView数据源,后者用于设置TableView结构和控制TableView相关事件。
func viewDidLoad() {
tableView.datasource = self
tableView.delegater = self
}
- 第一阶段对话,表格上有多少个区段(不同区段的Cell和布局可以不同)
func numberOfSection(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: nil) {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
return cell
}
哪一个Cell被选择
要得知哪一个Cell被选择了有两种办法:
- 实现tableView(_:didSelectedRowAt:)函数,通过参数就可以确定。
func tableView(_ tableView: UITableView, didSelectedRowAt indexPath: IndexPath) {
print(indexPath.row)
}
- 通过TableView的indexPathForSelectedRow属性。
let indexPath = tableView.indexPathForSelectedRow
改变Cell的顺序
当表格进入编辑状态后,用户可以用手指拖放的方式改变Cell的位置。但是要注意如果数据源没有随之变化,表格重新布局后顺序会恢复。
tableView.isEditing = true
- 实现tableView(:canMoveRowAt:)和 tableView(:moveRowAt:)函数,注意数据源顺序同样要变化(以list数组为例)
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
list.insert(
list.remove(at: sourceIndexPath.row), at: destinationIndexPath.row
)
}
- 如果进入编辑模式后,不想让那个使用者删除Cell的话,需要实现tableView(_:editingStyleForRowAt:),并且回传.none
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
删除Cell
当使用者将Cell向左滑动时,Cell右边会出现「Delete」或者「删除」,点击之后就可以删除Cell。
- 实现tableView(_:commit:forRawAt:)函数删除Cell和Cell中的数据(同样以list数组为例)
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRawAt indexPath: IndexPath) {
list.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
func tableView(_ tableView: UITableView, titileForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "删除此Cell"
}
刷新表格数据
表格数据源有变化时,直接调用tableView.reloadData()函数即可。
下拉刷新
比起点击刷新按钮来刷新表格,下拉手势更加编辑舒适,TableView内置了下拉刷新功能。
- 首先实现handleRefresh()函数处理刷新逻辑
@objc func handleRefresh() {
let formatter = DateFormatter()
fomatter.dateFormat = "hh:mm:ss"
let time = formatter.string(from: Date())
list.append(time)
tableView.refreshControl?.endRefreshing()
tableView.reloadData()
}
override func viewDidLoad() {
super.vieDidLoad()
tableView.refreshControl = UIRefreshControl()
tableview.refreshControl?.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
}
- 可以在viewDidAppear(_:)中设置提示文字
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tableView.refreshControl?.attributeTitle = NSAttributeString(string: "更新中...")
}
Cell的左滑或右滑按钮
当左滑Cell时,右方会出现删除按钮,除了删除按钮外,还可以设置别的按钮。同样可以设置右滑出现的按钮。 左滑需要实现tableView(_:trailingSwipeActionsConfigurationForRowAt:)函数;右滑需要实现tableVIew(:leadingSwipeActionsConfigurationForRowAt:)函数。(这里以左滑为例)
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let go = UIContextAction(style: .normal, title: "更多") {
(action, view, completionHandler) in
completionHandler(true)
}
go.backgroundColor = .blue
let del = UIContextAction(style: .destructive, title: "删除") {
(action, view, completionHandler) in
completionHandler(true)
}
let config = UISwipeActionsConfiguration(actions: [go, del])
config.performsfirstActionWithFullSwipe = false
return config
}
Cell高度
Cell的高度默认与Cell中的内容一致
Header与Footer
可以设置每个区段(Section)的Header与Footer样式,默认均为不显示。 以Header为例:
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "标题"
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> UIView? {
return yourView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 20
}
|