UITableView的简单理解

2020-05-08  本文已影响0人  aDou小夏

1.创建UITableView

_exampleTableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStylePlain];
创建UITableView对象,并设置代理和数数据源
_exampleTableView.delegate = self;
_exampleTableView.dataSource = self;

2.两种样式style

在创建UITableView的时候有两种样式,UITableViewStylePlain和UITableViewStyleGrouped
其中UITableViewStylePlain是默认的样式
区别:
1.有分区的时候
UITableViewStylePlain 区头和区尾是悬浮的
UITableViewStyleGrouped 当没有设置分区头时,会有默认的分区头的效果,区头和区尾是随cell一起滑动的

2.无分区的时候
UITableViewStylePlain 单元格会铺满整个UITableView

<!--去除线-->
_exampleTableView.separatorStyle = UITableViewCellSeparatorStyleNone;

3.注册单元格

[_exampleTableView registerClass:[firstTableViewCell class] forCellReuseIdentifier:cellFirstID];

4.实现代理和数据源中协议的方法

#pragma mark - UITableViewDelegate

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    exampleModel *model = _arrayExample[indexPath.row];
    return model.cellHeight;
}

#pragma mark - UITableViewDataSource

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return _arrayExample.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    firstTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellFirstID];
    exampleModel *model = _arrayExample[indexPath.row];
    [cell updateCellData:model];
    return cell;
}

3.代理方法(执行顺序)

numberOfSectionsInTableView(分区个数)
numberOfRowsInSection(每个分区有多少行)
heightForRowAtIndexPath(单元格高度)
cellForRowAtIndexPath(自定义单元格,当cell要显示的时候就会调用此方法)
先执行numberOfSectionsInTableView是因为UITableView继承于UIScrollview的
需要先设置UIScrollview的contentSize这个属性,UITableView才可以显示和滚动起来
然后调用cellForRowAtIndexPath将返回的视图添加到UIScrollview上.

4.UITableView的绘制

layoutSubviews
该方法是对子视图的布局,在第一次设置数据源的时候调用
UITableView是继承自UIScrollview,当当前视图的 size 变化时才会触发此方法(UITableView滑动的时候是因为改变了cell的高度所以才会导致layoutSubviews触发)
在布局前,要确定数据模型中已经缓存了所有高度.

reloadData
数据发生变化,需要重新刷新cell显示的内容,同时将所有显示的UITableViewCell和未显示可复用的UITableViewCell全部从父视图移除然后重新创建
需要重新计算相关的高度值,并缓存起来

5.UITableViewCell复用机制

第一种方式:

(1)定义一个全局的变量

static NSString *cellFirstID = @"cellFirst";

(2)注册cell

[_exampleTableView registerClass:[firstTableViewCell class] forCellReuseIdentifier:cellFirstID];

(3)在UITableViewDataSource的代理方法中获取或创建cell

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//去缓存池中查找是否有这个标识的cell  如果有那就取出来(取出来的前提是注册了cell)
//如果没有那就根据这个标识去创建对应的cell
firstTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellFirstID];
exampleModel *model = _arrayExample[indexPath.row];
[cell updateCellData:model];
return cell;
}

第二种方式:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//    当static关键字修饰局部变量时,只会初始化一次,并且在程序中只有一份内存
static NSString *cellFirstID = @"cell";
//去缓存池中查找是否有这个标识的cell(根据标识去取cell)  如果有就取出来
firstTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellFirstID];
//    如果缓存池中没有,则根据这个标识去创建一个cell
if (cell==nil) {
    cell = [[firstTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellFirstID];
}
exampleModel *model = _arrayExample[indexPath.row];
[cell updateCellData:model];
return cell;
}

总结:

(1)iOS设备的内存有限,不是每条数据都重新创建一个UITableViewCell,比如手机屏幕只能显示7行单元格,那么就会创建含有Identifier标识符的7个cell,这时候缓存池中是空的.
(2)当向上滑动的时候,上面的含有标识符的cell已经存放到缓存池中,当显示第8个单元格时,就会去访问缓存池,查看是否有这个Identifier,如果有直接从缓存池中获取.没有的话则会根据这个标识去创建一个cell.

上一篇下一篇

猜你喜欢

热点阅读