版權聲明:未經本人允許,禁止轉載.
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];
}