UITableView 是 iOS 開發(fā)中必不可少的一個控件,基本上每一個項目都會有多個地方會用到。詳細(xì)的了解UITableView的特性,對我們優(yōu)雅的使用它有莫大的幫助。
基本 API 解釋以及用法數(shù)據(jù)源 UITableViewDataSource
代理 UITableViewDelegate
UITableViewCell
一些常用操作
UITableView 進(jìn)階性能優(yōu)化
優(yōu)雅的使用 UITableView 之鏈?zhǔn)骄幊?/p>
UITableView 相關(guān)的開源庫MJRefresh 上拉下拉刷新組件
UITableView+FDTemplateLayoutCell 自動計算行高
SWTableViewCell Cell左右滑動操作
folding-cell 炫酷的 Cell 動畫效果
基本 API 解釋以及用法
數(shù)據(jù)源 UITableViewDataSource
// 返回分組數(shù) -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;// 返回每組行數(shù) -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;// 返回每行的單元格 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;// 返回每組頭標(biāo)題-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;// 返回每組尾部標(biāo)題-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;// 返回 Cell 是否在滑動時是否可以編輯-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;// 返回 Cell 是否可以移動-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;// TableView 右側(cè)建立一個索引表需要的數(shù)組內(nèi)容-(NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView; // 對 Cell 編輯結(jié)束后的回調(diào)-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;// 對 Cell 移動結(jié)束后的回調(diào)-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
代理 UITableViewDelegate自定義顯示效果
// Cell 即將顯示,可用于自定義 Cell 顯示的動畫效果-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;// UITableView 的 HeaderView 即將顯示,可用于自定義 HeaderView 顯示的動畫效果-(void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section;// UITableView 的 FooterView 即將顯示,可用于自定義 FooterView 顯示的動畫效果-(void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section;// Cell 完成顯示-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell )cell forRowAtIndexPath:(NSIndexPath)indexPath;// HeaderView 完成顯示-(void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);// FooterView 完成顯示-(void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section;
高度設(shè)置
// 返回每個 Cell 的高度-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;// 返回每個 Section 的 HeaderView 高度-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;// 返回每個 Section FooterView 的高度-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;// 自動計算 Cell 高度(iOS7.0 以后增加的,返回一個粗略值,系統(tǒng)會自動計算)-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;// 自動計算 Section 的 HeaderView 高度(iOS7.0 以后增加的)-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section;// 自動計算 Section 的 FooterView 高度(iOS7.0 以后增加的)-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section;
Section Header and Footer
// 返回 Section 自定義的 HeaderView-(nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section; // 返回 Section 自定義的 FooterView-(nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
Section 操作
// 返回當(dāng)前選中的 Row 是否高亮,一般在選擇的時候才高亮-(BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath;-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath;-(void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath;// Cell 被選中的回調(diào)-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
Editing
// 返回 Cell 編輯類型-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;// 怎樣編輯 Cell (iOS8.0 使用)-(NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath;// 設(shè)置進(jìn)入編輯狀態(tài)時,Cell不會縮進(jìn)-(BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath;// 開始編輯-(void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath __TVOS_PROHIBITED;//結(jié)束編輯-(void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(nullable NSIndexPath *)indexPath __TVOS_PROHIBITED;
iOS9.0 新特征———焦點
//(一些 iOS9.0 的新特征)// 返回能否獲得焦點-(BOOL)tableView:(UITableView *)tableView canFocusRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);// 返回是否將要更新焦點-(BOOL)tableView:(UITableView *)tableView shouldUpdateFocusInContext:(UITableViewFocusUpdateContext *)context NS_AVAILABLE_IOS(9_0);// 已經(jīng)更新焦點時調(diào)用-(void)tableView:(UITableView *)tableView didUpdateFocusInContext:(UITableViewFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator NS_AVAILABLE_IOS(9_0);// 返回上一個焦點的indexPath-(nullable NSIndexPath *)indexPathForPreferredFocusedViewInTableView:(UITableView *)tableView NS_AVAILABLE_IOS(9_0);
其他
// 單元格上的右指向按鈕的響應(yīng)方法回調(diào)-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;// 允許指定行移動到目標(biāo)行-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;// 縮進(jìn)-(NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath;
一些使用示例
//設(shè)置右滑編輯時出現(xiàn)的動作-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewRowAction *topRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"置頂" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { NSLog(@"1111"); }]; topRowAction.backgroundColor = [UIColor blueColor]; UITableViewRowAction *deleteRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"刪除" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { NSLog(@"2222"); }]; deleteRowAction.backgroundColor =[UIColor redColor]; return @[topRowAction, deleteRowAction];}
UITableViewCell3.1. 原生 UITableViewCell
UITableViewCell 自帶的四種格式
typedef NS_ENUM(NSInteger, UITableViewCellStyle) { UITableViewCellStyleDefault, UITableViewCellStyleValue1, UITableViewCellStyleValue2, UITableViewCellStyleSubtitle};

60019CFD-0AE9-4509-83BB-AED61B497E0C.png
UITableViewCell右側(cè)的 accessoryView 可以顯示不同的圖標(biāo),在iOS中稱之為訪問器,點擊可以觸發(fā)不同的事件,可以通過 UITableViewCellAccessoryType來設(shè)置。直接設(shè)置 accessoryView可以自定義
typedef NS_ENUM(NSInteger, UITableViewCellAccessoryType) { UITableViewCellAccessoryNone, // 不顯示任何圖標(biāo) UITableViewCellAccessoryDisclosureIndicator, // 跳轉(zhuǎn)指示圖標(biāo) UITableViewCellAccessoryDetailDisclosureButton, // 內(nèi)容詳情圖標(biāo)和跳轉(zhuǎn)指示圖標(biāo) UITableViewCellAccessoryCheckmark, // 勾選圖標(biāo) UITableViewCellAccessoryDetailButton // 內(nèi)容詳情圖標(biāo)};
設(shè)置 UITableViewCell 選擇時的背景顏色
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame]; cell.selectedBackgroundView.backgroundColor = [UIColor xxxxxx];
設(shè)置 UITableViewCell 選擇時的背景
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame]; cell.selectedBackgroundView.backgroundColor = [UIColor xxxxxx];
3.2. 自定義 UITableViewCell
一些常用操作
UITableView 進(jìn)階
性能優(yōu)化
關(guān)于 UITableView 的優(yōu)化,網(wǎng)上已經(jīng)有非常多的大神做出了總結(jié),這里沒有什么好說的。推薦來自優(yōu)酷的ibireme大神寫的這篇關(guān)于優(yōu)化的文章。這估計算是比較終極的優(yōu)化方案了。界面流暢度基本可以保持50 ~ 60FPS。http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/另外,如果 Cell 的復(fù)雜度不是特別高,但高度又是不確定的。推薦使用百度團(tuán)隊開源的 UITableView+FDTemplateLayoutCell ,自動計算及緩存 Cell 的高度,在加快開發(fā)進(jìn)度的同時,也能確保不錯的流暢度。
1.1. 確保重用 Cell1.2. 盡量減少 Cell 的視圖層級,并且少用或不用透明的視圖。避免離屏渲染,比如同時使用
view.layer.masksToBounds = YES; view.layer.cornerRadius = 20.0;
1.3. 提前計算并緩存 Cell 的高度
// 在這里返回提前計算好的高度,效率會明顯快很多。-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
1.4. 在滑動的時候按需加載關(guān)于這一點,可以看一下 VVeboTableViewDemo 的實踐。1.5. 異步繪制 Cell1.6. 盡量不在 cellForRowAtIndexPath 方法中做過多業(yè)務(wù)處理1.7. 減少使用 reloadData, 盡量使用下面方法來刷新列表。
//刷新指定的分組和行。-(void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);//刷新指定的分組。-(void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);//刪除時刷新指定的行數(shù)據(jù)。-(void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;//添加時刷新指定的行數(shù)據(jù)。-(void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
優(yōu)雅的使用 UITableView 之鏈?zhǔn)骄幊?/p>
UITableView 相關(guān)的開源庫
MJRefresh 上拉下拉刷新組件
UITableView+FDTemplateLayoutCell 自動計算行高
SWTableViewCell Cell左右滑動操作
folding-cell 炫酷的 Cell 動畫效果