UITableView
A view that presents data using rows arranged in a single column.
视图通过使用单列的行展示数据。
声明
@interface UITableView : UIScrollView
概述
iOS上的表格视图通过分行显示一列垂直滚动的内容。
UITableView的架构由headerview、cell、footview构成。
UITableViewDataSource
UITableView 作为视图,只负责展示,不管理数据。需要开发者手动实现datasource协议,为UITableView的cell提供数据。
@protocol UITableViewDataSource<NSObject>
@required
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
public protocol UITableViewDataSource : NSObjectProtocol {
@available(iOS 2.0, *)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
@available(iOS 2.0, *)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
}
以上代码是UITableViewDataSource协议必须实现的方法,展示了oc和swift版本。只有语言语法的差距,无论是oc转swift,还是swift补oc内容,只要掌握了ios的api的核心内容,学习起来是很容易的。
numberOfRowsInSection方法:对应section有多少行,如果未实现numberOfSectionsInTableView方法,tableview默认只有一个section。
cellForRowAt方法:对应指定的indexPath,实现cell是如何展现的,返回cell。
简单理解第一个方法就是告诉编译器数据的规模,第二个方法就是实现数据具体在每个section每行是如何展示的。
UITableViewCell
UITableViewCell是UITableView的核心内容,用于管理数据和数据在界面上的展示。系统提供基类UITableViewCell,我们可以定制需要的cell(继承自UITableViewCell)。UITableView的复用机制最大化的实现资源利用。
例如我们页面上只能展示15个cell的内容,想要获取更多的内容通过触摸滑动展示。cell的内容来源于数据库,数据库里面可能存储着千万个cell的数据。应用不可能将数据库中的每条数据都生成一个cell供tableview使用,那样的内存开销是巨大的。工程师便设计了复用的机制。
简单说就是当滑动 tableview 的时候,离开视图的cell会被放到复用池中,当下一个视图需要显示时,会先查看复用池是否有可复用的cell,如果有可复用的cell就取出来实现复用,没有可复用的cell就创建新的cell。
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"Studying";
self.view.backgroundColor = [UIColor whiteColor];
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
tableView.dataSource = self;
[self.view addSubview:tableView];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 200;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 创建cell,设置复用标识为@"id"
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"id"];
// 如果复用池中没有cell,新建cell
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"id"];
}
cell.textLabel.text = [NSString stringWithFormat:@"主标题 -- %@",@(indexPath.row)];
cell.detailTextLabel.text = @"副标题";
cell.imageView.image = [UIImage systemImageNamed:@"tv"];
return cell;
}
我们创建了一个tableview有1个section,200行cell,内容简单的显示行号。我们测试以下代码,可以创建断点。
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"id"];
// 创建一个全局变量
NSLog(@"cell创建多少次%i",cnt++);
}
app运行开始因为复用池中没有cell,需要创建一定量的cell,发现创建了19个cell。我们取消断点,跳过再标记断点并滚动tableview,发现没有触发断点也没有新的cell生成。这就是采用了tableview的复用机制。
2020-02-27 11:48:50.017535+0800 test[20640:3116779] cell创建多少次0
2020-02-27 11:48:50.022591+0800 test[20640:3116779] cell创建多少次1
2020-02-27 11:48:50.024561+0800 test[20640:3116779] cell创建多少次2
2020-02-27 11:48:50.026517+0800 test[20640:3116779] cell创建多少次3
2020-02-27 11:48:50.028336+0800 test[20640:3116779] cell创建多少次4
2020-02-27 11:48:50.030021+0800 test[20640:3116779] cell创建多少次5
2020-02-27 11:48:50.031608+0800 test[20640:3116779] cell创建多少次6
2020-02-27 11:48:50.033592+0800 test[20640:3116779] cell创建多少次7
2020-02-27 11:48:50.035560+0800 test[20640:3116779] cell创建多少次8
2020-02-27 11:48:50.037513+0800 test[20640:3116779] cell创建多少次9
2020-02-27 11:48:50.039401+0800 test[20640:3116779] cell创建多少次10
2020-02-27 11:48:50.041105+0800 test[20640:3116779] cell创建多少次11
2020-02-27 11:48:50.042972+0800 test[20640:3116779] cell创建多少次12
2020-02-27 11:48:50.044973+0800 test[20640:3116779] cell创建多少次13
2020-02-27 11:48:50.046594+0800 test[20640:3116779] cell创建多少次14
2020-02-27 11:48:50.048179+0800 test[20640:3116779] cell创建多少次15
2020-02-27 11:48:50.049757+0800 test[20640:3116779] cell创建多少次16
2020-02-27 11:48:50.051359+0800 test[20640:3116779] cell创建多少次17
2020-02-27 11:48:50.052858+0800 test[20640:3116779] cell创建多少次18
UITableViewDelegate
- 提供滚动过程中,UITableViewCell的出现、消失时机
- 提供 UITableViewCell 的高度、headerview和footerview的设置
- 提供 UITableViewCell 各种行为的回调(点击、删除等)
这里不做详细介绍,API中详细的方法。