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 styleUITableViewCellSeparatorStyleSingleLineEtched*/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 的设置
- 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 中的位置。
- UITableViewCell 结构
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;
// 获取指定行的 cellUITableViewCell *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区
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9