tableview 基础
本文讲讲tableview的基本使用. 顺便介绍一下delegation.
tableview用来做什么
tableview用来展示一个很长的list. 和android中的recyclerview不同, ios中的tableview只能是竖直方向的list.
如何写一个最简单的tableview
一个最简单的tableviewcontroller看起来像这样:
class viewcontroller: uitableviewcontroller {
var data: [string] = []
override func viewdidload() {
super.viewdidload()
// do any additional setup after loading the view.
// loaddata()
print(data)
}
override func tableview(_ tableview: uitableview, numberofrowsinsection section: int) -> int {
data.count
}
override func tableview(_ tableview: uitableview, cellforrowat indexpath: indexpath) -> uitableviewcell {
let cell = tableview.dequeuereusablecell(withidentifier: "mycell", for: indexpath)
cell.textlabel?.text = data[indexpath.row]
return cell
}
}
这里data是想展示的数据类型, 可以hardcode一些数据.
这么简单是因为这个viewcontroller继承了uitableviewcontroller, 并且cell的部分使用了storyboard.
这里需要用dequeuereusablecell方法, 是为了cell的复用, 因为list内容很多的时候cell view是可以循环使用的. (很像android里的recyclerview).
uitableviewcontroller的签名是这样:
open class uitableviewcontroller : uiviewcontroller, uitableviewdelegate, uitableviewdatasource {
它为我们做了以下三件事:
- 设置view为一个
uitableview. - 设置
delegate=self. - 设置
datasource=self.
这种方式的局限性在于第一点, 它的根view是一个tableview, 如果我们的需求比较复杂, 不仅仅是一个demo, 那么可能需要组合view.
拆解版tableview
我们也可以直接继承uiviewcontroller类, 然后自己动手做上面的几条设置.
delegate & datasource
tableview有两个重要的方面需要关注:
- uitableviewdelegate: 管理和用户的交互, 比如选择, 滑动手势等. 没有必须要实现的方法.
- uitableviewdatasource: 提供和管理数据, 包括了数据对应的cell或者header. 有两个必须要实现的方法(如上面的代码例子所示).
继承uiviewcontroller
继承uiviewcontroller而不是uitableviewcontroller之后, 需要自己写一个tableview并加在view里. 再分别实现uitableviewdelegate和uitableviewdatasource, 这里写在extension里, 拆分完之后set给tableview:
tableview.delegate = self tableview.datasource = self
整体改造后代码如下:
class viewcontroller: uiviewcontroller {
var data: [string] = ["hello", "world"]
private let tableview = uitableview()
override func loadview() {
view = uiview()
view.addsubview(tableview)
tableview.translatesautoresizingmaskintoconstraints = false
nslayoutconstraint.activate([
tableview.topanchor.constraint(equalto: view.topanchor),
tableview.bottomanchor.constraint(equalto: view.bottomanchor),
tableview.leadinganchor.constraint(equalto: view.leadinganchor),
tableview.trailinganchor.constraint(equalto: view.trailinganchor),
])
}
override func viewdidload() {
super.viewdidload()
tableview.register(mycell.self, forcellreuseidentifier: "mycell")
tableview.delegate = self
tableview.datasource = self
}
}
extension viewcontroller: uitableviewdelegate {}
extension viewcontroller: uitableviewdatasource {
func tableview(_: uitableview, numberofrowsinsection _: int) -> int {
data.count
}
func tableview(_: uitableview, cellforrowat indexpath: indexpath) -> uitableviewcell {
if let cell = tableview.dequeuereusablecell(withidentifier: "mycell", for: indexpath) as? mycell {
cell.configure(with: data[indexpath.row])
return cell
}
return uitableviewcell()
}
}
自己的cell class
这里cell也改用代码类, 写一个这样的类:
class mycell: uitableviewcell {
private let label = uilabel()
override init(style: uitableviewcell.cellstyle, reuseidentifier: string?) {
super.init(style: style, reuseidentifier: reuseidentifier)
contentview.addsubview(label)
label.translatesautoresizingmaskintoconstraints = false
nslayoutconstraint.activate([
label.topanchor.constraint(equalto: contentview.topanchor),
label.bottomanchor.constraint(equalto: contentview.bottomanchor),
label.leadinganchor.constraint(equalto: contentview.leadinganchor),
label.trailinganchor.constraint(equalto: contentview.trailinganchor),
])
}
@available(*, unavailable)
required init?(coder _: nscoder) {
fatalerror("init(coder:) has not been implemented")
}
func configure(with data: string) {
label.text = data
}
}
注意tableview注册这个cell类型:
override func viewdidload() {
super.viewdidload()
tableview.register(mycell.self, forcellreuseidentifier: "mycell")
}
补充知识: delegation
上面的方法初看可能会非常怪. 这里还涉及到了一个知识点是ios中的delegate. 它存在的意义是为了拓展本身类的功能.
apple自己的很多api就用了delegate protocol, 比如uiapplicationdelegate, uitableviewdelegate. 如果我们想自己定义一个:
protocol mytypedelegate: anyobject {
func mytype(_ mytype: mytype,
shoulddosomething argumentstring: string) -> bool
func mytype(_ mytype: mytype,
didabortwitherror error: error)
func mytypedidfinish(_ mytype: mytype)
}
class mytype {
weak var delegate: mytypedelegate?
}
定义delegation的几个原则:
- 方法名以被代理的类型开头.
- 方法的第一个参数是被代理的对象.
references
以上就是ios系列学习tableview展现一个list实例的详细内容,更多关于ios tableview展现list的资料请关注代码网其它相关文章!
发表评论