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的资料请关注代码网其它相关文章!
发表评论