版权声明:未经本人允许,禁止转载.
1. TableView初始化
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
- 1.UITableView有两种风格:UITableViewStylePlain(普通样式)和UITableViewStyleGrouped(分组样式)
- 2.UITableView显示数据需要设置数据源dataSource,执行操作需要设置代理delegate
2. TableView的属性和方法
1. 设置高度
- 设置cell,分区头(header),分区尾(footer)的高度
//属性设置 设置表中所有的对象
tableView.rowHeight = 50;
tableView.sectionHeaderHeight = 40;
tableView.sectionFooterHeight = 40;
//delegate
//返回指定indexPath的Row的高度时调用
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 50;
}
//返回指定分区(section)的Header的高度时调用
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 40;
}
//返回指定分区(section)的Footer的高度时调用
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 40;
} - 估算cell,分区头(header),分区尾(footer)的高度 (iOS 7 or later)
//属性设置 设置表中所有的对象
tableView.estimatedRowHeight = 50;
tableView.estimatedSectionHeaderHeight = 40;
tableView.estimatedSectionFooterHeight = 40;
//delegate
//估算指定indexPath的Row的高度调用
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 50;
}
//估算指定分区(section)的Header的高度时调用
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section {
return 40;
}
//估算指定分区(section)的Footer的高度时调用
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section {
return 40;
}
估算高度(estimatedHeight)是为了加快tableView的加载速度,设置估算高度后,conteSize.height根据 cell的估算值 * cell的个数 计算,contentSize会随着滚动从估算慢慢替换成真实高度,结果会导致滚动条的大小处于不稳定状态,甚至出现"跳跃".
- 常量UITableViewAutomaticDimension (iOS 5 or later)
//cell(iOS 8 or later)
tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension
在UITableViewStyleGrouped情况下,动态计算TableView的headerTitle和FooterTitle的高度
在iOS 8之后,可以动态计算cell的高度,要求必须使用autoLayout
2.设置cell的分割线(separator)
- 设置分割线缩进
属性: separatorInset (iOS 7 or later) 在代码情况下正常
tableView.separatorInset = UIEdgeInsetsMake(0, 30, 0, 50); - 设置分割线类型
属性: separatorStyle 为枚举类型
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
enum {
UITableViewCellSeparatorStyleNone,//没分割线
UITableViewCellSeparatorStyleSingleLine,//单线(默认)
UITableViewCellSeparatorStyleSingleLineEtched//只支持UITableViewStyleGrouped,不过看起来没什么效果
} - 设置分割线颜色
属性: separatorColor
//默认为灰色
tableView.separatorColor = [UIColor cyanColor]; - 设置分割线模糊化(毛玻璃效果)
属性: separatorEffect (iOS 8 or later)
分割线会根据背景色模糊化
UIImageView *bg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"launchImage.png"]];
tableView.backgroundView = bg;
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect];
tableView.separatorEffect = vibrancyEffect;
3.设置分区索引栏 (SectionIndex)
- 设置索引栏显示所需最小cell的数量
属性: sectionIndexMinimumDisplayRowCount
//cell个数 >= 20 显示索引栏
tableView.sectionIndexMinimumDisplayRowCount = 20; - 设置索引栏字体颜色
属性: sectionIndexColor (iOS 6 or later)
tableView.sectionIndexColor = [UIColor redColor]; - 设置索引栏背景色
属性: sectionIndexBackgroundColor (iOS 7 or later)
tableView.sectionIndexBackgroundColor = [UIColor cyanColor]; - 设置索引栏点击时的背景色
属性: sectionIndexTrackingBackgroundColor (iOS 6 or later)
tableView.sectionIndexTrackingBackgroundColor = [UIColor blackColor]; - 设置索引栏内容
数据源: - sectionIndexTitlesForTableView:
返回索引数组,对应相应的分区
- (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return @[@"0",@"1",@"2",@"3",@"10",@"20"];
} - 设置各个索引对应的分区
数据源: - tableView:sectionForSectionIndexTitle:atIndex:
通过title和index确定索引,返回该索引指定的分区
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
if ([title isEqualToString:@"10"]){
return 0;
}else if(index == 5) {
return 1;
}
return index;
} - 刷新分区索引栏 (iOS 3.0 or later)
调用方法: - reloadSectionIndexTitles
[tableView reloadSectionIndexTitles];
4.设置背景View,表头,表尾
- 设置TableView背景的View
一般用于设置背景图片等,会自适应大小
属性: backgroundView (iOS 3.2 or later)
UIImageView *bg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Image.png"]];
tableView.backgroundView = bg; - 设置表格的表头
表格最上部添加辅助的View,不会悬停
属性: tableHeaderView
tableView.tableHeaderView = [self tableHeaderView];
- (UIView *)tableHeaderView {
UILabel *headerView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 80)];
headerView.backgroundColor = [UIColor orangeColor];
headerView.text = @"表头";
headerView.textAlignment = NSTextAlignmentCenter;
return headerView;
} - 设置表格的表尾
表格最下部添加辅助View,不会悬停
属性: tableFooterView
tableView.tableFooterView = [self tableFooterView];
- (UIView *)tableFooterView {
UILabel *footerView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 80)];
footerView.backgroundColor = [UIColor orangeColor];
footerView.text = @"表尾";
footerView.textAlignment = NSTextAlignmentCenter;
return footerView;
}
5.设置分区头(header)和分区尾(footer)
- 注册HeaderFooterView (iOS 6.0 or later)
注册Xib
调用方法: - registerNib:forHeaderFooterViewReuseIdentifier:
[tableView registerNib:[UINib nibWithNibName:@"TableHeaderFooterView" bundle:nil] forHeaderFooterViewReuseIdentifier:footerView];
注册Class
调用方法: - registerClass:forHeaderFooterViewReuseIdentifier:
[tableView registerClass:[TableHeaderFooterView class] forHeaderFooterViewReuseIdentifier:headerView]; - 获取重用的HeaderFooterView (iOS 6.0 or later)
调用方法: - dequeueReusableHeaderFooterViewWithIdentifier:
TableHeaderFooterView *view = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerView]; - 创建HeaderFooterView
获取指定分区(section)的HeaderView时调用
代理: - tableView:viewForHeaderInSection:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
TableHeaderFooterView *view = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerView];
view.textLabel.text = [NSString stringWithFormat:@"第%ld分区头",section];
return view;
}
获取指定分区(section)的FooterView时调用
代理: - tableView:viewForFooterInSection:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
TableHeaderFooterView *view = [tableView dequeueReusableHeaderFooterViewWithIdentifier:footerView];
view.name.text = [NSString stringWithFormat:@"第%ld分区尾",section];
return view;
} - 设置HeaderFooterTitle (HeaderFooterView优先级大于title)
设置指定分区(section)的title (HeaderTitle)
数据源: - tableView:titleForHeaderInSection:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [NSString stringWithFormat:@"第%ld分区头",section];
}
设置指定分区(section)的title (FooterTitle)
数据源: - tableView:titleForFooterInSection:
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
return [NSString stringWithFormat:@"第%ld分区尾",section];
} - 设置修改指定分区(section)的HeaderFooterView (iOS 6.0 or later)
HeaderView将要显示时调用
代理: - tableView:willDisplayHeaderView:forSection:
FooterView将要显示时调用
代理: - tableView:willDisplayFooterView:forSection:
//headerView将要出现
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
TableHeaderFooterView *header = (TableHeaderFooterView *)view;
header.contentView.backgroundColor = [UIColor yellowColor];
}
//footerView将要出现
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(nonnull UIView *)view forSection:(NSInteger)section {
if (section == 0) {
TableHeaderFooterView *footer = (TableHeaderFooterView *)view;
footer.bgView.backgroundColor = [UIColor greenColor];
}
}
HeaderView已经消失时调用
代理: - tableView:didEndDisplayingHeaderView:forSection:
FooterView已经消失时调用
代理: - tableView:didEndDisplayingFooterView:forSection:
//headerView已经消失
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(nonnull UIView *)view forSection:(NSInteger)section {
TableHeaderFooterView *header = (TableHeaderFooterView *)view;
header.textLabel.textAlignment = NSTextAlignmentRight;
}
//footerView已经消失
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(nonnull UIView *)view forSection:(NSInteger)section {
if (section == 1) {
TableHeaderFooterView *footer = (TableHeaderFooterView *)view;
footer.bgView.backgroundColor = [UIColor orangeColor];
}
} - 返回HeaderFooterView (iOS 6.0 or later)
返回指定分区(section)的HeaderView
调用方法: - headerViewForSection:
TableHeaderFooterView *headerView = (TableHeaderFooterView *)[tableView headerViewForSection:indexPath.section];
headerView.contentView.backgroundColor = [UIColor blackColor];
返回指定分区(section)的FooterView
调用方法: - footerViewForSection:
TableHeaderFooterView *footerView = (TableHeaderFooterView *)[tableView footerViewForSection:indexPath.section];
footerView.bgView.backgroundColor = [UIColor grayColor]; - 返回HeaderFooterView的大小Rect
返回指定分区(section)的大小(HeaderRect)
调用方法: - rectForHeaderInSection:
CGRect headerRect = [tableView rectForHeaderInSection:indexPath.section];
NSLog(@"分区头大小 = %@",NSStringFromCGRect(headerRect));
返回指定分区(section)的大小(FooterRect)
调用方法: - rectForFooterInSection:
CGRect footerRect = [tableView rectForFooterInSection:indexPath.section];
NSLog(@"分区尾大小 = %@",NSStringFromCGRect(footerRect));
6.设置分区(section)
- 设置表格分区数
数据源: - numberOfSectionsInTableView:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 4;
} - 返回表格分区数
属性:numberOfSections
NSInteger number = tableView.numberOfSections; - 返回指定分区(section)的大小
调用方法: - rectForSection:
CGRect sectionRect = [tableView rectForSection:indexPath.section];
NSLog(@"分区大小 = %@",NSStringFromCGRect(sectionRect)); - 设置动画块
调用方法: - beginUpdates 和 - endUpdates
两个方法成对使用,表示一个动画块.在动画块中可以对表格执行多个连续的插入,删除,移动等操作
[self.tableView beginUpdates];
[self.tableView insertSections:set withRowAnimation:UITableViewRowAnimationLeft];
[self.tableView deleteSections:set withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates]; - 通过指定的动画,在指定位置插入分区(1个或多个)
调用方法 - insertSections:withRowAnimation: 插入分区时,需要修改分区数目
- (void)insertSection {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 3)];
self.sectionNum += 3;
[self.tableView insertSections:set withRowAnimation:UITableViewRowAnimationLeft];
} - 通过指定的动画,删除指定的分区(1个或多个)
调用方法 - deleteSections:withRowAnimation: 删除分区时,需要修改分区数目
- (void)deleteSection {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)];
if (self.sectionNum >= 2) {
self.sectionNum -= 2;
[self.tableView deleteSections:set withRowAnimation:UITableViewRowAnimationTop];
}
} - 通过指定的动画,刷新指定的分区(1个或多个)
调用方法 - reloadSections:withRowAnimation:
- (void)reloadSection {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)];
[self.tableView reloadSections:set withRowAnimation:UITableViewRowAnimationTop];
} - 将指定分区移动到另一个位置 (iOS 5.0 or later)
调用方法 - moveSection:toSection:
- (void)moveSection {
[self.tableView moveSection:1 toSection:2];
}
7.设置TableViewCell
- 注册cell
注册Xib (iOS 5.0 or later)
调用方法 - registerNib:forCellReuseIdentifier:
[tableView registerNib:[UINib nibWithNibName:@"TableViewCell" bundle:nil] forCellReuseIdentifier:tableViewCell2];
注册Class (iOS 6.0 or later)
调用方法 - registerClass:forCellReuseIdentifier:
[tableView registerClass:[TableViewCell class] forCellReuseIdentifier:tableViewCell1]; - 返回重用的cell
方法1: - dequeueReusableCellWithIdentifier: 适用于cell为空时申请空间
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableViewCell1];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableViewCell1];
}
方法2: - dequeueReusableCellWithIdentifier:forIndexPath: (iOS 6.0 or later) 适用于注册的cell或storyboard中的cell
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath]; - 设置指定indexPath的cell
必须实现的方法
数据源: - tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = (indexPath.section < 2) ? tableViewCell1:tableViewCell2;
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
//前两个分区为Cell1
if (indexPath.section < 2) {
cell.textLabel.text = [NSString stringWithFormat:@"test %ld %ld",indexPath.section,indexPath.row];
}else {//其余的为Cell2
cell.name.text = [NSString stringWithFormat:@"%ld",indexPath.section];
cell.title.text = [NSString stringWithFormat:@"%ld",indexPath.row];
}
cell.backgroundColor = [UIColor clearColor];
return cell;
} - 修改指定indexPath的cell
cell将要显示时调用(willDisplay)
代理: - tableView:willDisplayCell:forRowAtIndexPath:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
cell.contentView.backgroundColor = [UIColor purpleColor];
}
}
cell已经消失时调用 (iOS 6.0 or later)
代理: - tableView:didEndDisplayingCell:forRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 2) {
cell.contentView.backgroundColor = [UIColor blueColor];
}
} - 返回指定indexPath对应的cell
调用方法: - cellForRowAtIndexPath:
TableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor greenColor]; - 返回指定indexPath的row的Rect
调用方法: - rectForRowAtIndexPath:
CGRect cellRect = [tableView rectForRowAtIndexPath:indexPath];
NSLog(@"cell大小 = %@",NSStringFromCGRect(cellRect)); - 返回可见区域内cell数组
属性:visibleCells
NSArray *cellArr = tableView.visibleCells;
NSLog(@"可见cell数组:%@",cellar); - 设置指定分区(section)中row的个数
必须实现的方法
数据源: - tableView:numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.rowNum;
} - 返回指定分区(section)中row的个数
调用方法: - numberOfRowsInSection:
NSInteger rowNum = [tableView numberOfRowsInSection:indexPath.section];
NSLog(@"该分区row的个数 = %ld",rowNum);
8.NSIndexPath (UITableView)
- indexPath包括分区(section)和行(row)
初始化: + indexPathForRow:inSection:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:2 inSection:0];
NSLog(@"section = %ld, row = %ld",indexPath.section,indexPath.row); - 返回指定点所在row对应的indexPath
调用方法: - indexPathForRowAtPoint:
NSIndexPath *indexPath2 = [tableView indexPathForRowAtPoint:cellRect.origin];
NSLog(@"section = %ld, row = %ld",indexPath2.section,indexPath2.row); - 返回指定cell对应的indexPath
调用方法: - indexPathForCell:
NSIndexPath *indexPath3 = [tableView indexPathForCell:cell];
NSLog(@"section = %ld, row = %ld",indexPath3.section,indexPath3.row); - 返回选中row对应的indexPath
属性: - indexPathForSelectedRow
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSLog(@"section = %ld, row = %ld",indexPath.section,indexPath.row); - 返回指定区域(Rect)内所有rows对应的indexPath数组
调用方法: - indexPathsForRowsInRect:
NSArray *indexPathArr1 = [self.tableView indexPathsForRowsInRect:self.view.bounds];
NSLog(@"%@",indexPathArr1); - 返回表格中所有可见行(rows)对应的indexPath数组
属性: indexPathsForVisibleRows
NSArray *indexPathArr2 = [self.tableView indexPathsForVisibleRows];
NSLog(@"%@",indexPathArr2); - 返回表格中所有选中行(rows)对应的indexPath数组
属性: indexPathsForSelectedRows (iOS 5.0 or later)
NSArray *indexPathArr3 = self.tableView.indexPathsForSelectedRows;
NSLog(@"%@",indexPathArr3);
9.选择(Selecte)和滚动(Scroll)
- 设置是否允许选择(非编辑状态下) 默认Yes
属性: allowsSelection (iOS 3.0 or later)
tableView.allowsSelection = YES; - 设置表格编辑状态下是否允许选择 默认为NO
属性: allowsSelectionDuringEditing
tableView.allowsSelectionDuringEditing = YES; - 设置表格是否允许多选(非编辑状态下) 默认为NO
属性: allowsMultipleSelection (iOS 5.0 or later)
tableView.allowsMultipleSelection = YES; - 设置表格编辑状态下是否允许多选 默认为NO
属性: allowsMultipleSelectionDuringEditing (iOS 5.0 or later)
tableView.allowsMultipleSelectionDuringEditing = YES; - 设置表格选中指定indexPath的row
调用方法: - selectRowAtIndexPath:animated:scrollPosition:
最后一个参数决定选定cell的显示位置
[tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionTop]; - 设置表格中指定indexPath的row的选中取消
调用方法: - deselectRowAtIndexPath:animated:
[tableView deselectRowAtIndexPath:indexPath animated:YES]; - 用户将要选中某行时触发
可以指定一些indexPath不能选择,或选择不同的row都是选择同一个indexPath:
代理: - tableView:willSelectRowAtIndexPath:
//指定row == 0不能选择
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
return nil;
}
return indexPath;
} - 用户完成选中某行时触发
可以做选中之后的操作
代理: - tableView:didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//取消选择状态
[tableView deselectRowAtIndexPath:indexPath animated:YES];
} - 用户将要取消选中行时触发
代理: - tableView:willDeselectRowAtIndexPath: (iOS 3.0 or later)
//指定row == 1 不能取消选中
- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 1) {
return nil;
}
return indexPath;
} - 用户完成取消选中行时触发
做一些取消选中后的操作
代理: - tableView:didDeselectRowAtIndexPath: (iOS 3.0 or later)
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
TableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor orangeColor];
}