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.
网友评论