iOS开发之UITableView详解

时间:2022-09-19 20:20:42

一、uitableview基本介绍

默认的uitableview有2种风格:

  1. uitableviewstyleplain(不分组)
  2. uitableviewstylegrouped(分组)

uitableview中的数据只有行的概念,没有列的概念,uitableview的每行数据就是一个uitableviewcell。
自带的uitableviewcell的类型选择有:

 

复制代码 代码如下:

typedef ns_enum(nsinteger, uitableviewcellstyle) {
    uitableviewcellstyledefault,    // 左侧显示textlabel(不显示detailtextlabel),imageview可选(显示在最左边)
    uitableviewcellstylevalue1,     // 左侧显示textlabel、右侧显示detailtextlabel(默认蓝色),imageview可选(显示在最左边)
    uitableviewcellstylevalue2,     // 左侧依次显示textlabel(默认蓝色)和detailtextlabel,imageview可选(显示在最左边)
    uitableviewcellstylesubtitle    // 左上方显示textlabel,左下方显示detailtextlabel(默认灰色),imageview可选(显示在最左边)
};

 

二、uitableviewdatasource数据源

数据源的作用就是告诉uitableview,我该显示什么数据

 

复制代码 代码如下:

#pragma mark 常用数据源方法
#pragma mark 返回分组数
- (nsinteger)numberofsectionsintableview:(uitableview *)tableview
#pragma mark 返回每组行数
- (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section
#pragma mark 返回每行的单元格
- (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath
#pragma mark 返回每组头标题名称
- (nsstring *)tableview:(uitableview *)tableview titleforheaderinsection:(nsinteger)section
#pragma mark 返回每组尾部说明
- (nsstring *)tableview:(uitableview *)tableview titleforfooterinsection:(nsinteger)section

 

计算分组数 -> 计算每组行数 -> 生成分组索引 -> 生成单元格
注意:cellforrowatindexpath只生产当前显示在界面上的单元格

三、uitableviewdelegate代理

代理的作用是告诉uitableview,我该怎么显示和响应

 

复制代码 代码如下:

#pragma mark - 常用代理方法
#pragma mark 设置分组头部的内容高度
- (cgfloat)tableview:(uitableview *)tableview heightforheaderinsection:(nsinteger)section
#pragma mark 设置每行高度(每行高度可以不一样)
- (cgfloat)tableview:(uitableview *)tableview heightforrowatindexpath:(nsindexpath *)indexpath
#pragma mark 设置分组尾部的内容高度
- (cgfloat)tableview:(uitableview *)tableview heightforfooterinsection:(nsinteger)section
#pragma mark 点击了某一行
- (void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath
#pragma mark 设置分组的头部视图
- (uiview *)tableview:(uitableview *)tableview viewforheaderinsection:(nsinteger)section;
#pragma mark 设置分组的尾部视图
- (uiview *)tableview:(uitableview *)tableview viewforfooterinsection:(nsinteger)section;

 

四、uitableview刷新列表方法

 

复制代码 代码如下:

#pragma mark 刷新整个表格
- (void)reloaddata;
#pragma mark 刷新指定的行
- (void)reloadrowsatindexpaths:(nsarray *)indexpaths withrowanimation:(uitableviewrowanimation)animation;
#pragma mark 刷新指定的分组
- (void)reloadsections:(nsindexset *)sections withrowanimation:(uitableviewrowanimation)animation;
#pragma mark 删除时刷新指定的行数据
- (void)deleterowsatindexpaths:(nsarray *)indexpaths withrowanimation:(uitableviewrowanimation)animation;
#pragma mark 添加时刷新指定的行数据
- (void)insertrowsatindexpaths:(nsarray *)indexpaths withrowanimation:(uitableviewrowanimation)animation;

 

五、uitableviewcell的重用机制

在uitableview内部有一个缓存池,专门用来缓存uitableviewcell,因为uitableview不是一下子显示全部cell,而是以 所见即所得 的方式,手机上看的见的cell,才有存在的对象uitableviewcell实例。具体表现如下:

每次显示新的cell的时候,都是先从缓存池中取出对应的uitableviewcell对象,进行 重新初始化 显示。如果缓存池中没有,才创建新的uitableviewcell对象
每当某个cell被移出 可见区域 外后,就会被 回收 到缓存池中
所以尽管要展示的数据巨大,但内存中存在的uitableviewcell也是有限的,极大的降低了对内存的需求。

 

复制代码 代码如下:

# pragma mark 在tableview:cellforrowatindexpath:方法中使用uitableview的重用机制
// 由于此方法调用十分频繁,cell的标示声明成静态变量有利于性能优化
static nsstring *cellidentifier = @"uitableviewcellidentifierkey1";
// 首先根据标识去缓存池取
uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:cellidentifier];
// 如果缓存池没有找到,则重新创建并放到缓存池中
if(!cell){
    cell = [[uitableviewcell alloc] initwithstyle:uitableviewcellstylevalue1 reuseidentifier:cellidentifier];
}

 

六、系统自带的uitableviewcell

iOS开发之UITableView详解

我们基本上很少使用系统自带的uitableviewcell,样式太过于死板了。

七、自定义cell

基本步骤:
自定义类xxxtableviewcell,继承uitableviewcell
重写-(id)initwithstyle:reuseidentifier:方法,添加子控件
最好重写layoutsubview方法,设置子控件frame
然后在uitableview的代理方法tableview:cellforrowatindexpath:中使用重用机制创建该类xxxtableviewcell,再对cell进行初始化

iOS开发之UITableView详解

八、mvc模式

iOS开发之UITableView详解