iOS文檔補(bǔ)完計劃--UITableViewDataSource&&UITableViewDelegate

目錄主要分為以下幾個樣式:
常用为迈、會用、了解

目錄

  • UITableViewDataSource
  • 配置TableView
    • tableView:cellForRowAtIndexPath:
    • tableView:numberOfRowsInSection:
    • numberOfSectionsInTableView:
    • tableView:titleForHeaderInSection:
    • tableView:titleForFooterInSection:
  • 插入&&刪除
    • tableView:commitEditingStyle:forRowAtIndexPath:
    • tableView:canEditRowAtIndexPath:
  • 重新排序
    • tableView:canMoveRowAtIndexPath:
    • tableView:moveRowAtIndexPath:toIndexPath:
  • 索引設(shè)置
    • sectionIndexTitlesForTableView:
    • tableView:sectionForSectionIndexTitle:atIndex:
  • UITableViewDelegate
  • 配置Row
    • tableView:heightForRowAtIndexPath:
    • tableView:estimatedHeightForRowAtIndexPath:
    • tableView:indentationLevelForRowAtIndexPath:
    • tableView:willDisplayCell:forRowAtIndexPath:
    • tableView:shouldSpringLoadRowAtIndexPath:withContext:
  • 擴(kuò)展按鈕
    • tableView:editActionsForRowAtIndexPath:
    • tableView:accessoryButtonTappedForRowWithIndexPath:
  • 選擇管理
    • tableView:willSelectRowAtIndexPath:
    • tableView:didSelectRowAtIndexPath:
    • tableView:willDeselectRowAtIndexPath:
    • tableView:didDeselectRowAtIndexPath:
  • 頁眉和頁腳
    iOS11需要注意的新特性
  • 編輯表單(左滑)
    • tableView:willBeginEditingRowAtIndexPath:
    • tableView:didEndEditingRowAtIndexPath:
    • tableView:editingStyleForRowAtIndexPath:
    • tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:
    • tableView:shouldIndentWhileEditingRowAtIndexPath:
  • 重新排序表單
    • tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:
  • 移動出可見范圍
    • cell/sectionHeaderView/sectionFooterView的消失
  • MENU菜單
  • 高亮管理

UITableViewDataSource

一個能夠為UITableView提供展示要素的代理


配置TableView

  • tableView:cellForRowAtIndexPath:

將返回的Cell插入TableView的indexPath位置键闺。(一旦需要展示cell)則必須實現(xiàn)且不能返回nil。

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath;

返回的對象通常是重用的cell。

  • - tableView:numberOfRowsInSection:

返回該節(jié)有多少行內(nèi)容(必須實現(xiàn)

- (NSInteger)tableView:(UITableView *)tableView 
 numberOfRowsInSection:(NSInteger)section;
  • numberOfSectionsInTableView:

返回一共有多少節(jié)內(nèi)容需要展示

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

默認(rèn)返回1

  • - tableView:titleForHeaderInSection:
  • - tableView:titleForFooterInSection:

為系統(tǒng)默認(rèn)樣式的sectionHeader/sectionFooter設(shè)置文字

- (NSString *)tableView:(UITableView *)tableView 
titleForHeaderInSection:(NSInteger)section;

除了敲demo通常沒啥用创坞。你應(yīng)該使用tableView:viewForHeaderInSection:進(jìn)行自定義樣式平酿。


插入&&刪除

  • - tableView:commitEditingStyle:forRowAtIndexPath:

編輯完成時調(diào)用

- (void)tableView:(UITableView *)tableView 
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle 
forRowAtIndexPath:(NSIndexPath *)indexPath;

如果點擊其他地方被取消凤优、則不會被調(diào)用。

editingStyle是一個枚舉蜈彼、有三種可能的值

typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) {
    UITableViewCellEditingStyleNone,//沒有編輯樣式
    UITableViewCellEditingStyleDelete,//刪除樣式 (左邊是紅色減號)
    UITableViewCellEditingStyleInsert//插入樣式  (左邊是綠色加號)
};

當(dāng)你進(jìn)行了對應(yīng)的操作(點擊了綠色的添加或者紅色的刪除)筑辨、代理將會告知你并讓你修改數(shù)據(jù)源以配合操作。

  • - tableView:canEditRowAtIndexPath:

返回該位置的cell是否可以進(jìn)入編輯狀態(tài)

- (BOOL)tableView:(UITableView *)tableView 
canEditRowAtIndexPath:(NSIndexPath *)indexPath;

如果沒有實現(xiàn)此方法幸逆、那么默認(rèn)所有的cell都可以進(jìn)入編輯狀態(tài)棍辕。
這個編輯狀態(tài)有兩種意思:

  1. 通過[self.tableView setEditing:YES animated:YES];讓所有cell進(jìn)入
  2. 右滑

重新排序

讓tableView支持拖動、需要以下條件

  1. 讓tableView進(jìn)入編輯狀態(tài)
    也就是設(shè)置它的editing為YES

  2. 返回編輯模式
    也就是實現(xiàn)UITableViewDelegate中的tableview:editingStyleForRowAtIndexPath:方法还绘,在里面返回UITableViewCellEditingStyleNone模式楚昭。如果不實現(xiàn),默認(rèn)返回的就是刪除模式

3拍顷、實現(xiàn)tableView:moveRowAtIndexPath:toIndexPath方法
只要實現(xiàn)該方法抚太,就能實現(xiàn)單元格的拖動排序,但只是實現(xiàn)了表面的排序昔案,并沒有修改真實地數(shù)據(jù)

4尿贫、在方法中完成數(shù)據(jù)模型的更新

  • tableView:canMoveRowAtIndexPath:

是否可以將該cell拖動到指定位

- (BOOL)tableView:(UITableView *)tableView 
canMoveRowAtIndexPath:(NSIndexPath *)indexPath;

返回該單元格、是否可以被拖動爱沟。默認(rèn)返回YES帅霜。

  • - tableView:moveRowAtIndexPath:toIndexPath:

拖動完成時觸發(fā)、讓用戶修改數(shù)據(jù)源

- (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath 
      toIndexPath:(NSIndexPath *)destinationIndexPath;

如果不做修改呼伸、cell就僅僅是在當(dāng)前展示上修改了位置身冀。下次被提取或者刷新時會變回原來的順序钝尸。


索引設(shè)置

  • - sectionIndexTitlesForTableView:

返回索引數(shù)組

- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView;
  1. tablbView的style必須是UITableViewStylePlain
  2. 返回的數(shù)組將會懸浮在tableView右側(cè)
  • - tableView:sectionForSectionIndexTitle:atIndex:

點擊索引后、將talbeView移動至哪個section處

- (NSInteger)tableView:(UITableView *)tableView 
sectionForSectionIndexTitle:(NSString *)title 
               atIndex:(NSInteger)index;

支持?jǐn)?shù)組越界


UITableViewDelegate

對頁眉頁腳搂根、高度珍促、選擇、刪除等操作進(jìn)行支持剩愧。


配置Row

  • - tableView:heightForRowAtIndexPath:

可以為指定的行設(shè)置高度

- (CGFloat)tableView:(UITableView *)tableView 
heightForRowAtIndexPath:(NSIndexPath *)indexPath;

你可以rowHeight為所有的cell統(tǒng)一設(shè)置高度猪叙、相對性能較高。
而一旦實現(xiàn)heightForRowAtIndexPath方法仁卷、你就必須為每一個indexPath設(shè)置高度穴翩。
返回UITableViewAutomaticDimension則由系統(tǒng)自適應(yīng)計算。

  • - tableView:estimatedHeightForRowAtIndexPath:

返回指定位置的預(yù)估行高

- (CGFloat)tableView:(UITableView *)tableView 
estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
  1. 如果沒有預(yù)估锦积、可以返回UITableViewAutomaticDimension芒帕。
  2. 使用此功能可以將某些計算、從加載時移動到滾動時進(jìn)行丰介。以提高性能背蟆。
  • - tableView:indentationLevelForRowAtIndexPath:

返回縮進(jìn)級別

- (NSInteger)tableView:(UITableView *)tableView 
indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath;

并不知道有什么地方必須這樣用


  • - tableView:willDisplayCell:forRowAtIndexPath:

某個indexPath的cell將要被繪制(展示)

- (void)tableView:(UITableView *)tableView 
  willDisplayCell:(UITableViewCell *)cell 
forRowAtIndexPath:(NSIndexPath *)indexPath;

由于cellForRow實際上會預(yù)創(chuàng)建一些cell、所以cell內(nèi)部的賦值可以放在這里哮幢、以提升一些性能带膀。
但是最顯著的用途還是對剛展示出來的cell做一些動畫吧。比如從右側(cè)一個一個滑入之類橙垢。

  • - tableView:shouldSpringLoadRowAtIndexPath:withContext:

cell是否支持iOS11 新特性 Drag and Drop (默認(rèn)YES)

- (BOOL)tableView:(UITableView *)tableView 
shouldSpringLoadRowAtIndexPath:(NSIndexPath *)indexPath 
      withContext:(id<UISpringLoadedInteractionContext>)context;

擴(kuò)展按鈕

  • - tableView:editActionsForRowAtIndexPath:

自定義左滑事件

- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView 
                  editActionsForRowAtIndexPath:(NSIndexPath *)indexPath;

返回一個由UITableViewRowAction組成的數(shù)組垛叨。
他們會響應(yīng)用對應(yīng)的點擊交互。
如果你不實現(xiàn)這個代理柜某、右滑時將會展示默認(rèn)按鈕点额。

  • - tableView:accessoryButtonTappedForRowWithIndexPath:

當(dāng)cell的擴(kuò)展視圖被點擊時調(diào)用

- (void)tableView:(UITableView *)tableView 
accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;

這里的擴(kuò)展視圖指的是cell.accessoryType的視圖。如下圖所示:


選擇管理

cell被點擊時引起的一系列方法調(diào)用

需要注意的是即使cell.selectionStyle = UITableViewCellSelectionStyleNone;使得cell跟隨點擊而改變背景色莺琳、以下方法也會被調(diào)用还棱。

  • - tableView:willSelectRowAtIndexPath:

將要被選定時觸發(fā)

- (NSIndexPath *)tableView:(UITableView *)tableView 
  willSelectRowAtIndexPath:(NSIndexPath *)indexPath;

允許你通過返回一個新的NSIndexPath、來修改將要被選擇的cell惭等。
編輯狀態(tài)下不會觸發(fā)此方法

  • - tableView:didSelectRowAtIndexPath:

cell被選定時觸發(fā)

- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath;

編輯狀態(tài)下不會觸發(fā)此方法

  • - tableView:willDeselectRowAtIndexPath:

選中狀態(tài)被取消時觸發(fā)

- (NSIndexPath *)tableView:(UITableView *)tableView 
willDeselectRowAtIndexPath:(NSIndexPath *)indexPath;

如果你返回nil珍手、將不會被取消。允許從定向

  • - tableView:didDeselectRowAtIndexPath:

cell選中被取消時觸發(fā)

- (void)tableView:(UITableView *)tableView 
didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;

頁眉和頁腳

//返回頁眉和頁腳
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section; 
- (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section; 

//返回頁眉和頁腳的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;

//頁眉和頁腳將要展示
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);

//預(yù)估頁眉和頁腳高度
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section NS_AVAILABLE_IOS(7_0);
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section NS_AVAILABLE_IOS(7_0);

以上的方法通過方法名基本都能理解其用處辞做。

這里需要注意

iOS11之后琳要、系統(tǒng)為我們設(shè)置了預(yù)估行高。如果只實現(xiàn)了header高度為0.1f秤茅、而沒有返回具體的view會引起留白的bug稚补。《詳見》


編輯表單

要讓表單支持左滑

你必須實現(xiàn)commitEditingStyle方法、以告訴tableView左滑操作是由價值的

  • - tableView:willBeginEditingRowAtIndexPath:

表單即將進(jìn)入編輯模式(左滑)

- (void)tableView:(UITableView *)tableView 
willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath;
  • -tableView:didEndEditingRowAtIndexPath:

已經(jīng)離開編輯模式

- (void)tableView:(UITableView *)tableView 
didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath;

編輯接觸(并不限于取消)觸發(fā)框喳、并不會記錄你執(zhí)行了哪種操作课幕。
所以厦坛、你應(yīng)該在tableView:commitEditingStyle:forRowAtIndexPath:而不是這里實現(xiàn)相關(guān)編輯操作。

  • - tableView:editingStyleForRowAtIndexPath:

決定左滑返回哪種附加視圖

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView 
           editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;

默認(rèn)返回UITableViewCellEditingStyleDelete

typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) {
    UITableViewCellEditingStyleNone,//沒有編輯樣式
    UITableViewCellEditingStyleDelete,//刪除樣式 (左邊是紅色減號)
    UITableViewCellEditingStyleInsert//插入樣式  (左邊是綠色加號)
};
  • - tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:

更改UITableViewCellEditingStyleDelete下的文字

- (NSString *)tableView:(UITableView *)tableView 
titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath;

setEditing以及左滑時同樣有效乍惊。

  • - tableView:shouldIndentWhileEditingRowAtIndexPath:

進(jìn)入編輯模式時杜秸、cell背景是否縮進(jìn)

- (BOOL)tableView:(UITableView *)tableView 
shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath;

通知委托在編輯模式下是否需要對表視圖指定行進(jìn)行縮進(jìn),NO為關(guān)閉縮進(jìn)润绎,這個方法可以用來去掉move時row前面的空白撬碟。


重新排序表單

  • tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:

在移動cell的時候會多次調(diào)用

- (NSIndexPath *)tableView:(UITableView *)tableView 
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath 
       toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;

cell的初始位置以及目標(biāo)。允許對目標(biāo)位置重定向莉撇。
移動中的留白動畫呢蛤、以及結(jié)果都會受此影響。


移動出可見范圍

cell/sectionHeaderView/sectionFooterView的消失

//cell已經(jīng)移動出可見范圍
- (void)tableView:(UITableView *)tableView 
didEndDisplayingCell:(UITableViewCell *)cell 
forRowAtIndexPath:(NSIndexPath *)indexPath;

//sectionHeaderView已經(jīng)移動出可見范圍
- (void)tableView:(UITableView *)tableView 
didEndDisplayingHeaderView:(UIView *)view 
       forSection:(NSInteger)section;

//sectionFooterView已經(jīng)移動出可見范圍
- (void)tableView:(UITableView *)tableView 
didEndDisplayingFooterView:(UIView *)view 
       forSection:(NSInteger)section;

MENU菜單

如果想讓cell支持menu菜單的呼出棍郎、必須將以下三個方法全部實現(xiàn)

  • - tableView:shouldShowMenuForRowAtIndexPath:

長按后是否顯示編輯菜單

- (BOOL)tableView:(UITableView *)tableView 
shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath;
  • - tableView:canPerformAction:forRowAtIndexPath:withSender:

返回該cell支持那種action

- (BOOL)tableView:(UITableView *)tableView 
 canPerformAction:(SEL)action 
forRowAtIndexPath:(NSIndexPath *)indexPath 
       withSender:(id)sender;

這個規(guī)則你可以參考iOS文檔補(bǔ)完計劃--UIResponder中關(guān)于canPerformAction:withSender:方法的解釋顾稀。

  • - tableView:performAction:forRowAtIndexPath:withSender:

讓代理者對menu操作進(jìn)行響應(yīng)

- (void)tableView:(UITableView *)tableView 
    performAction:(SEL)action 
forRowAtIndexPath:(NSIndexPath *)indexPath 
       withSender:(id)sender;

高亮管理

高亮權(quán)限、高亮坝撑、取消高領(lǐng)

//點擊時是否高亮。默認(rèn)YES
- (BOOL)tableView:(UITableView *)tableView 
shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath;

//已經(jīng)高亮
- (void)tableView:(UITableView *)tableView 
didHighlightRowAtIndexPath:(NSIndexPath *)indexPath;


//不再高亮
- (void)tableView:(UITableView *)tableView 
didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath;

最后

本文主要是自己的學(xué)習(xí)與總結(jié)粮揉。如果文內(nèi)存在紕漏巡李、萬望留言斧正。如果愿意補(bǔ)充以及不吝賜教小弟會更加感激扶认。


參考資料

官方文檔-UITableView
iOS UITableView 的 Plain和Grouped樣式的區(qū)別
iOS_UITableView 編輯(cell的插入, 刪除, 移動)
ios tableView那些事 (五) 給tableview設(shè)置縮進(jìn)級別
關(guān)于UITableView委托方法的功能(by atany)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末侨拦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子辐宾,更是在濱河造成了極大的恐慌狱从,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叠纹,死亡現(xiàn)場離奇詭異季研,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)誉察,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門与涡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人持偏,你說我怎么就攤上這事驼卖。” “怎么了鸿秆?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵酌畜,是天一觀的道長。 經(jīng)常有香客問我卿叽,道長桥胞,這世上最難降的妖魔是什么恳守? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮埠戳,結(jié)果婚禮上井誉,老公的妹妹穿的比我還像新娘。我一直安慰自己整胃,他們只是感情好颗圣,可當(dāng)我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屁使,像睡著了一般在岂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蛮寂,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天蔽午,我揣著相機(jī)與錄音,去河邊找鬼酬蹋。 笑死及老,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的范抓。 我是一名探鬼主播骄恶,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼匕垫!你這毒婦竟也來了僧鲁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤象泵,失蹤者是張志新(化名)和其女友劉穎寞秃,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體偶惠,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡春寿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了忽孽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片堂淡。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖扒腕,靈堂內(nèi)的尸體忽然破棺而出绢淀,到底是詐尸還是另有隱情,我是刑警寧澤瘾腰,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布皆的,位于F島的核電站,受9級特大地震影響蹋盆,放射性物質(zhì)發(fā)生泄漏费薄。R本人自食惡果不足惜硝全,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望楞抡。 院中可真熱鬧伟众,春花似錦、人聲如沸召廷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽竞慢。三九已至先紫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筹煮,已是汗流浹背遮精。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留败潦,地道東北人本冲。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像劫扒,于是被迫代替她去往敵國和親檬洞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,955評論 2 355