1、系统tableView 的创建
- 遵守 UITableViewDelegate, UITableViewDataSource 协议
1.1 数据源 初始化
// 声明数据源,必须声明为全局变量
@property(nonatomic, retain)NSMutableArray *myDataArray;
// 数据源数组初始化,定义一个可变数组做为表格的数据源
myDataArray = [[NSMutableArray alloc] init];
NSArray *array1 = @[@"UIWindow", @"UIApplication", @"UIView", @"UILabel",
@"UIProgressView", @"UIAlertView", @"UIActionSheet", @"UIPickerView"];
NSArray *array2 = @[@"窗口", @"应用", @"视图", @"标签", @"进度条", @"警告框",
@"操作表", @"选择框", @"风火轮", @"图像视图", @"网页视图", @"滚动视图",
@"多行文本视图"];
// 向数据源中添加数据
[myDataArray addObject:array1];
[myDataArray addObject:array2];
// 声明表格视图对象,头标题和脚标题悬浮显示,默认类型
UITableView *myTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
// 设置 tableView 的代理
myTableView.delegate = self;
myTableView.dataSource = self;
// 将 tableView 添加到窗口中
[self.view addSubview:myTableView];
// 设置分段数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// 数据源数组为多维数组时,用数组计算
return myDataArray.count;
}
// 设置行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// section 段,返回每段中有多少行
return [[myDataArray objectAtIndex:section] count];
}
// 设置每一行显示的内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 创建标识词,随意设置,但不能和其它 tableView 的相同
static NSString *indentifier = @"testIdentifier";
// 根据标志词先从复用队列里查找
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:indentifier];
// 复用队列中没有时再创建
if (cell == nil) {
// 创建新的 cell,默认为主标题模式
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indentifier];
}
// 设置每一行显示的文字内容
cell.textLabel.text = [[myDataArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
// indexPath.section 分段数,indexPath.row 行数,设置图片内容,图片在 Cell 的左端,图片大小自动压缩
cell.imageView.image = [UIImage imageNamed:@"HQ_0003"];
return cell;
}
2、tableView 的设置
// 将数组指向新的空间,可以不提前申请空间(不初始化)
myDataArray = @[array1, array2];
// 将数组里的所有数据替换成新的,必须提前申请空间
myDataArray.array = @[array1, array2];
// 设置分段的头标题和脚标题的类型
/*
UITableViewStylePlain, // 简单模式,每个分段之间紧密连接,头脚标题悬浮显示,默认类型
UITableViewStyleGrouped // 分组模式,每个分段之间分开,头脚标题跟随移动,头标题英文自动大写
*/
// 头标题和脚标题悬浮显示,默认类型
UITableView *myTableView = [[UITableView alloc] init];
UITableView *myTableView = [[UITableView alloc] initWithFrame:frame];
// 带显示类型的设置
UITableView *myTableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStyleGrouped];
// 设置分段的头标题高度,UITableViewDelegate 协议方法
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 40;
}
// 设置分段的脚标题高度,UITableViewDelegate 协议方法
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 30;
}
// 设置分段的头标题内容,UITableViewDataSource 协议方法
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (0 == section) {
return @"English Header";
}
else {
return @"中文 Header";
}
}
// 设置分段的脚标题内容,UITableViewDataSource 协议方法
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
if (0 == section) {
return @"English Footer";
}
else {
return @"中文 Footer";
}
}
// 分段头标题视图,UITableViewDelegate 协议方法,返回自定义的标题视图
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (!section) {
label.text = @"English Header";
}
else{
label.text = @"中文 Header";
}
return label;
}
// 分段脚标题视图,UITableViewDelegate 协议方法
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
if (!section) {
label.text = @"English Footer";
}
else{
label.text = @"中文 Footer";
}
// 返回自定义的标题视图
return label;
}
// 设置表格的表头视图
/*
只有视图的高度设置起作用
*/
myTableView.tableHeaderView = myHeaderView;
// 设置表格的表尾视图
/*
只有视图的高度设置起作用
*/
myTableView.tableFooterView = myFooterView;
// 设置表格的背景视图
myTableView.backgroundView = myImageView;
// 设置表格的背景颜色
myTableView.backgroundColor = [UIColor blueColor];
// 设置表格的分割线颜色
/*
设置为 clearColor 时即可隐藏(不显示)所有分割线
*/
myTableView.separatorColor = [UIColor redColor];
// 设置表格的分割线类型
/*
UITableViewCellSeparatorStyleNone, // 没有分割线
UITableViewCellSeparatorStyleSingleLine, // 单线型,默认
// 嵌刻线型,This separator style is only supported for grouped style
UITableViewCellSeparatorStyleSingleLineEtched
*/
myTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
// 设置表格的分割线边距
/*
上、左、下、右,只有左、右设置有效
设置左边距时会使标题相应的右移
左边距设置为 0 时,分割线不会紧靠左边框
*/
myTableView.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);
// 清除表格多余的分割线
/*
表格为 UITableViewStylePlain 类型时,若表格的内容没有占满屏幕时,没有设置内容的部分表格也会有分割线
创建自定义的 view,将该 view 的背景颜色清空(默认为透明),并添加到表格的脚视图上
*/
myTableView.tableFooterView = [[UIView alloc] init];
// 设置表格分割线左边距为零
[myTableView setSeparatorInset:UIEdgeInsetsZero];
[myTableView setLayoutMargins:UIEdgeInsetsZero];
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
// UITableViewDelegate 协议方法
[cell setSeparatorInset:UIEdgeInsetsZero];
[cell setLayoutMargins:UIEdgeInsetsZero];
}
// 自定义表格分割线
/*
系统分割线的左边无法紧靠表格左边框,隐藏系统分割线,自定义视图,添加到 Cell 的下边实现
同时可以清除表格在 UITableViewStylePlain 类型时的多余分割线
*/
myTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
if (cell == nil) {
// 创建新的 cell
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indentifier];
// 添加自定义分割线视图
CGRect frame = CGRectMake(0, cell.contentView.bounds.size.height, self.view.bounds.size.width, 1);
UIView *mySeparatorView = [[UIView alloc] initWithFrame:frame];
mySeparatorView.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.5];
[cell.contentView addSubview:mySeparatorView];
}
// 属性设置
/*
设置全部行的高度,默认为 44
*/
myTableView.rowHeight = 60;
// 协议方法设置
/*
可单独设置每一行的高度,默认为 44
*/
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60;
}
// 设置估计行高
/*
设置全部行的高度
*/
self.tableView.estimatedRowHeight = 80;
// 协议方法设置估计行高
/*
可单独设置每一行的估计行高
*/
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 80;
}
// 设置自动计算行高
self.tableView.rowHeight = UITableViewAutomaticDimension;
// 打开表格的编辑模式
/*
default is NO. setting is not animated
*/
myTableView.editing = YES;
// 翻转表格的编辑模式
myTableView.editing = !myTableView.editing;
// 翻转表格的编辑模式
[myTableView setEditing:!myTableView.editing animated:YES];
// 设置表格普通模式下是否允许单选
/*
default is YES. Controls whether rows can be selected when not in editing mode
*/
myTableView.allowsSelection = YES;
// 设置表格在编辑模式下是否允许单选
/*
default is NO. Controls whether rows can be selected when in editing mode
*/
myTableView.allowsSelectionDuringEditing = YES;
// 设置表格普通模式下是否允许多选
/*
default is NO. Controls whether multiple rows can be selected simultaneously
*/
myTableView.allowsMultipleSelection = YES;
// 设置表格在编辑模式下是否允许多选
/*
default is NO. Controls whether multiple rows can be selected simultaneously in editing mode
*/
myTableView.allowsMultipleSelectionDuringEditing = YES;
// 取消表格选择
/*
在表格选中协议方法中设置,表格点击变色后恢复原来颜色,设置后无法实现表格多选
*/
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// 重载表格视图
/*
重走所有的表格视图方法,刷新所有的表格
*/
[tableView reloadData];
// 重载某一分段
[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
// 重载某一个行
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
// 删除一个 cell
/*
只刷新删除的 cell
*/
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
// 插入一个 cell
/*
只刷新插入的 cell
*/
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
3、Cell 的创建(系统类型 Cell)
- 使用 dequeueReuseableCellWithIdentifier: 可不注册,但是必须对获取回来的 cell 进行判断是否为空,若空则手动创建新的 cell;
- 使用 dequeueReuseableCellWithIdentifier: forIndexPath: 必须注册,但返回的 cell 可省略空值判断的步骤。
- tableViewCell 的复用机制:
- 1、当一个 cell 滑出屏幕的时候,会被放到复用队列里(系统自动操作)。
- 2、当一个 cell 即将出现的时候,我们需要先从复用队列里查找,找到就直接用,找不到就创建。
- 系统 Cell 的创建方式:
- 代码创建 cell。
- 注册 cell。
- 从 storyboard 加载 cell。
3.1 创建 Cell
// 设置每一行显示的内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 创建标识词,标识词随意设置,但不能和其它 tableView 的相同
static NSString *resumeID = @"testIdentifier";
// 根据标识词先从复用队列里查找
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:resumeID];
// 复用队列中没有时再创建
if (cell == nil) {
// 创建新的 cell,默认为主标题模式
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:resumeID];
}
// 设置每一行显示的文字内容,覆盖数据
cell.textLabel.text = [[myDataArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:@"HQ_0003"];
return cell;
}
3.2 注册 Cell
- 在 tableView 创建时,从 iOS7 开始多了一种创建 cell 的方式(注册),让 tableView 注册一种 cell,需要设置复用标志。
- 创建的 Cell 为 UITableViewCellStyleDefault 默认类型,无法修改。
// 定义重用标识,定义为全局变量
NSString *resumeID = @"testIdentifier";
// 注册 cell
- (void)viewDidLoad {
[super viewDidLoad];
// 注册某个标识对应的 cell 类型
[myTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:resumeID];
}
// 设置每一行显示的内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 根据标识词先从复用队列里查找,复用队列中没有时根据注册的 cell 自动创建
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:resumeID forIndexPath:indexPath];
// 设置每一行显示的文字内容,覆盖数据
cell.textLabel.text = [[myDataArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:@"HQ_0003"];
return cell;
}
4、Cell 的设置
- 自定义Cell的流程
- UITableView 的每一行都是一个 UITableViewCell,通过 dataSource的tableView:cellForRowAtIndexPath: 方法来初始化每一行。
- UITableViewCell 内部有个默认的子视图 contentView,contentView 是 UITableViewCell 所显示内容的父视图,可显示一些辅助指示视图。
- 辅助指示视图的作用是显示一个表示动作的图标,可以通过设置 UITableViewCell 的 accessoryType 来显示,
- 默认是 UITableViewCellAccessoryNone (不显示辅助指示视图)。
- contentView 下默认有 3 个子视图
- 其中 2 个是 UILabel (通过 UITableViewCell 的 textLabel 和 detailTextLabel 属性访问)。
- 第 3 个是 UIImageView (通过 UITableViewCell 的 imageView 属性访问)。
- UITableViewCell 还有一个 UITableViewCellStyle 属性,用于决定使用 contentView 的哪些子视图,以及这些子视图在 contentView 中的位置。
![1213778-20180804221257540-1803507463.png](https://images2018.cnblogs.com/blog/1213778/201808/1213778-20180804221257540-1803507463.png)
- UITableViewCell 结构
![1213778-20180804221308472-793839893.png](https://images2018.cnblogs.com/blog/1213778/201808/1213778-20180804221308472-793839893.png)
4.1 设置 Cell 的类型
/*
UITableViewCellStyleDefault, // 可选图片 + 主标题模式,默认
UITableViewCellStyleValue1, // 可选图片 + 左右主副标题模式,两端对齐
UITableViewCellStyleValue2, // 左右主副标题模式,中间对齐
UITableViewCellStyleSubtitle // 可选图片 + 上下主副标题模式
*/
// 主标题模式,默认类型
cell = [[UITableViewCell alloc] init];
// 设置类型
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"testIdentifier"];
// 主标题模式
// 设置主标题内容
cell.textLabel.text = [[myDataArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
// 设置图片内容,图片在 Cell 的左端,图片大小自动压缩
cell.imageView.image = [UIImage imageNamed:@"HQ_0003"];
// 主副标题模式
// 设置主标题内容
cell.textLabel.text = [[myDataArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
// 设置副标题内容
cell.detailTextLabel.text = [NSString stringWithFormat:@"第 %li 行", indexPath.row];
// 设置图片内容,图片在 Cell 的左端,图片大小自动压缩
cell.imageView.image = [UIImage imageNamed:@"HQ_0003"];
4.3 往 cell 上添加自定义 view
- 不是直接添加在 cell 上,cell 给我们提供了一个专门用来添加子 view 的东西,当 cell 被复用的时候,不允许创建对象,
- 如果想给系统的 cell 上添加一些子 view,需要在创建 cell 的时候添加,然后在复用的时候修改子 view 显示的内容。
// 添加 cell 自定义 view 视图
UILabel *myCellView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 44)];
myCellView.tag = 100;
// 在创建新的 cell 后添加
[cell.contentView addSubview:myCellView];
// 设置 cell 自定义 view 显示内容,在 cell 复用的时候设置
UILabel *myCellView = (id)[self.view viewWithTag:100];
myCellView.text = [NSString stringWithFormat:@"自定义 Cell View %@",
[[myDataArray objectAtIndex:indexPath.section]
objectAtIndex:indexPath.row]];
// Cell 的背景视图设置
/*
设置自定义视图为 Cell 背景视图
图片大小自动压缩填充
*/
cell.backgroundView = myBackgroundView;
// Cell 选中时的背景视图设置
cell.selectedBackgroundView = myBackgroundView;
// Cell 背景颜色的设置
cell.backgroundColor = [UIColor yellowColor];
// 设置 cell 被点击时的颜色
/*
UITableViewCellSelectionStyleNone, // 无色,表格点击时无颜色变化
UITableViewCellSelectionStyleBlue, // 灰色
UITableViewCellSelectionStyleGray, // 灰色
UITableViewCellSelectionStyleDefault // 灰色,默认
*/
cell.selectionStyle = UITableViewCellSelectionStyleDefault;
// 取消表格选择变色
/*
在表格选中协议方法中设置,表格点击变色后恢复原来颜色,设置后无法实现表格多选
*/
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Cell 附属控件类型的设置
/*
如果附属控件里有 button ,这个 button 会独立出来
UITableViewCellAccessoryNone, // 无附属控件,默认
UITableViewCellAccessoryDisclosureIndicator, // 箭头,不能点击
UITableViewCellAccessoryDetailDisclosureButton, // 详情按钮和箭头,可以点击
UITableViewCellAccessoryCheckmark, // 对号,不能点击
UITableViewCellAccessoryDetailButton // 详情按钮,可以点击
*/
cell.accessoryType = UITableViewCellAccessoryCheckmark;
// Cell 附属控件视图的设置
/*
设置自定义视图为 Cell 的附属控件,需设置 view 的大小
*/
cell.accessoryView = myAccessoryView;
// 获取指定行的 cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]];
// 获取所有被选中的行
NSArray *indexPaths = [tableView indexPathsForSelectedRows];
5、自定义数据模型的创建与引用
@interface BookModel : NSObject
// 根据需要使用的数据创建数据模型属性变量
@property(nonatomic, copy)NSString *title;
@property(nonatomic, copy)NSString *detail;
@property(nonatomic, copy)NSString *icon;
@property(nonatomic, copy)NSString *price;
+ (instancetype)bookModelWithDict:(NSDictionary *)dict;
@end
+ (instancetype)bookModelWithDict:(NSDictionary *)dict {
BookModel *model = [[self alloc] init];
// KVC - Key Value Coding
[model setValuesForKeysWithDictionary:dict];
return model;
}
// 向数据源中添加数据
// 定义数据源
@property(nonatomic, retain)NSArray *myDataArray;
// 懒加载
- (NSArray *)myDataArray {
if (_myDataArray == nil) {
// 加载 plist 中的字典数组
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"bookData" ofType:@"plist"];
NSArray *bookDataArray = [NSArray arrayWithContentsOfFile:filePath];
// 字典数组 -> 模型数组
NSMutableArray *dataArrayM = [NSMutableArray arrayWithCapacity:bookDataArray.count];
for (NSDictionary *bookInfoDic in bookDataArray) {
BookModel *bookModel = [BookModel bookModelWithDict:bookInfoDic];
[dataArrayM addObject:bookModel];
}
// 将从文件中取出的数据添加到数据源数组中
_myDataArray = [dataArrayM copy];
}
return _myDataArray;
}
// 从数据源中取出数据
// UITableViewDataSource 协议方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 从数据源数组中取出数据
BookModel *bookModel = [self.myDataArray objectAtIndex:indexPath.row];
// 配置自定义 Cell 子视图上显示的内容
cell.book = bookModel;
}
6、自定义tableView区