iOS App中UITableView左滑出現(xiàn)刪除按鈕及其cell的重用
UITableView的編輯模式
實(shí)現(xiàn)UITableView簡單的刪除功能(左滑出現(xiàn)刪除按鈕)
首先UITableView需要進(jìn)入編輯模式。實(shí)現(xiàn)下面的方法,即使什么代碼也不寫也會進(jìn)入編輯模式:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
}
當(dāng)點(diǎn)擊出現(xiàn)的Delete按鈕時,會調(diào)用上面這個方法,所以在這個方法里面可以實(shí)現(xiàn)進(jìn)行刪除操作的一些邏輯,比如:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// 首先修改model
[self.books removeObjectAtIndex:indexPath.row];
// 之后更新view
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
如果想要修改Delete這個按鈕的文本,可以實(shí)現(xiàn)下面的代理方法:
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
return @"刪除";
}
這種方式可以很快捷的實(shí)現(xiàn)系統(tǒng)自帶的簡單刪除方法,并且當(dāng)UITableView進(jìn)入編輯模式的時候(出現(xiàn)Delete按鈕),繼續(xù)點(diǎn)擊cell則會自動取消編輯模式,非常方便。
在一些應(yīng)用中可能會看到,當(dāng)用戶點(diǎn)擊一個按鈕的時候,UITableView里面的cell的左邊會出現(xiàn)一個紅色圓,里面是一個-,當(dāng)點(diǎn)擊這個-的時候會出現(xiàn)左滑效果,出現(xiàn)Delete按鈕。如何實(shí)現(xiàn)的呢?
UITableView有一個editing屬性,如果將這個屬性設(shè)置為YES,那么就會進(jìn)入編輯模式;同樣,設(shè)置為NO,就會退出。
上面的提到的例子,當(dāng)用戶點(diǎn)擊按鈕的時候,就進(jìn)入編輯模式,編輯模式默認(rèn)的形式就是在左邊有一個紅色-,當(dāng)用戶點(diǎn)擊的時候自帶左滑效果出現(xiàn)Delete按鈕。當(dāng)用戶點(diǎn)擊Delete按鈕的時候又會調(diào)用上面提到的方法。
所以說了這么多,只需要將editing設(shè)置為YES并實(shí)現(xiàn)上面的方法就可以達(dá)到上述效果。
UITableViewCell的重用
UITableViewCell如果在tableView:cellForRowAtIndexPath:方法中,像其他類一樣,使用下面的方式創(chuàng)建:
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text = @"hello";
...
這樣雖然能正確顯示,但是性能是有問題的。
蘋果實(shí)際上是幫我們提高了性能了的。假設(shè)要顯示200行數(shù)據(jù),如果同時創(chuàng)建200個cell,那么無疑會非常消耗性能,并且并沒有太大的意義——因為有些cell根本還沒有顯示出來。
所以在使用UITableView的時候,只有在cell即將顯示的時候才會調(diào)用tableView:cellForRowAtIndexPath:方法,也就是說,如果有200行數(shù)據(jù),那么只會創(chuàng)建我們可以看到的cell,而那些看不到的數(shù)據(jù),則不會創(chuàng)建對應(yīng)的cell。
比如在手機(jī)屏幕上可以同時顯示5個cell(編號為0 - 4),那么當(dāng)用戶向上滑tableView的時候,第6個cell即將出現(xiàn),而第1個cell還未消失,所以此時會創(chuàng)建6個UITableViewCell。當(dāng)?shù)?個cell出現(xiàn),那么第1個cell就會完全從屏幕上消失,此時這個UITableViewCell的對象將被銷毀,并且第7個cell被創(chuàng)建。以此類推,當(dāng)有新的cell出現(xiàn),那么就會創(chuàng)建一個新的cell,銷毀消失的那個cell。
這樣雖然不必同時創(chuàng)建200個cell,但是在不斷地創(chuàng)建-銷毀cell,性能上依然會有問題。
蘋果提供的更好的方法是將cell復(fù)用,而不是銷毀。
每次有新的cell出現(xiàn)的時候(也就是tableView:cellForRowAtIndexPath:方法執(zhí)行的時候),不應(yīng)該直接創(chuàng)建一個cell,而是應(yīng)該去緩沖池中查找有沒有可復(fù)用的cell,如果有,那么就重用這個cell;如果沒有,則創(chuàng)建一個cell。這樣無論數(shù)據(jù)是200行,2000行還是20000行,實(shí)際上創(chuàng)建的只是屏幕可見的cell的個數(shù)。
還是上面的例子,當(dāng)?shù)?個cell即將出現(xiàn),第1個cell消失,此時并不會銷毀第一個cell,而是將它放入緩沖池中等待復(fù)用。此時第7個cell會首先去緩沖池中尋找是否有可復(fù)用的cell,發(fā)現(xiàn)有(就是消失的第1個cell),那么就會拿來復(fù)用,而不是重新創(chuàng)建。這樣一來,消失一個,下次就會重用這個,這樣就可以保證創(chuàng)建最少數(shù)量的cell,仍然可以滿足需求。
實(shí)現(xiàn)cell的重用可以采用下面的方法:
使用代碼自己來創(chuàng)建新的cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * const cellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
cell.backgroundColor = [UIColor greenColor];
}
cell.textLabel.text = @"hello";
return cell;
}
這里有幾點(diǎn)需要注意:
當(dāng)cell為nil,需要創(chuàng)建新的cell的時候,使用的是initWithStyle:reuseIdentifier:方法,而不是init方法,這樣做是因為創(chuàng)建新的cell的時候需要綁定一個identifier,這樣在重用的時候才能找到可重用的相同類型。如果使用init方法則沒有綁定identifier,這樣在重用的時候無法成功找到對應(yīng)的可重用的cell。
一般在if(!cell)中,也就是在新創(chuàng)建cell的時候,將一些只需要初始化一次的屬性進(jìn)行初始化,而不是在這個括號的外面。因為在括號外面會執(zhí)行多次,而這些屬性并不需要多次設(shè)置。同樣,如果不同的cell需要設(shè)置不同屬性或數(shù)據(jù),那么需要在括號外執(zhí)行,因為括號外面每次cell出現(xiàn)都會執(zhí)行到,這樣可以保證不用的cell對應(yīng)不同的屬性或數(shù)據(jù)。如果將本該設(shè)置不同cell對應(yīng)不同屬性的代碼放在括號里面,在復(fù)用cell的時候不會重新覆蓋這些數(shù)據(jù),會出現(xiàn)不正確的結(jié)果,早晨數(shù)據(jù)冗余的問題。
另一種方法是自動創(chuàng)建新的cell:
NSString * const cellIdentifier = @"CellIdentifier";
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
cell.textLabel.text = @"hello";
return cell;
}
首先需要注冊class,意思就是告訴tableView,首先去緩沖池中找有沒有可重用的cell,如果有,則拿過來重用;如果沒有,那么根據(jù)之前注冊的UITableViewCell這個類,來自動生成一個cell,并且給它綁定上重用identifier。
這個方法省去了我們自己手動創(chuàng)建cell,但是也有不足:蘋果提供給我們的cell的樣式,除了默認(rèn)的,我們都不能用了。
第一種方法我們通過手動創(chuàng)建cell,使用initWithStyle:reuseIdentifier:可以傳入不同的style來創(chuàng)建蘋果為我們提供的cell,但是在第二種方法中無法實(shí)現(xiàn)了。
第二種方法更多的時候用在我們自定義Cell。雖然無法使用更多的系統(tǒng)自帶樣式,但是我們首先可以注冊自定義的cell的類(將UITableViewCell換成自定義的Cell),然后仍然首先去緩沖池中找有沒有可重用cell,如果沒有,則根據(jù)注冊的cell來創(chuàng)建cell并綁定identifier。當(dāng)然,在使用dequeueReusableCellWithIdentifier:的時候,返回的應(yīng)該也是自定義的Cell類型。
注冊的不僅可以是Class,還可以是nib,也就是說可以注冊通過xib創(chuàng)建的cell,和上面的方法同理。
還可以直接通過Storyboard,設(shè)置好prototype cell的identifier,在dequeueReusableCellWithIdentifier:中就可以直接使用cell,既不用提前注冊,也不用手動創(chuàng)建cell。
- 詳解iOS中Button按鈕的狀態(tài)和點(diǎn)擊事件
- 關(guān)于iOS導(dǎo)航欄返回按鈕問題的解決方法
- IOS UITableViewCell詳解及按鈕點(diǎn)擊事件處理實(shí)例
- iOS開發(fā)中UISwitch按鈕的使用方法簡介
- 詳解iOS應(yīng)用中自定義UIBarButtonItem導(dǎo)航按鈕的創(chuàng)建方法
- 詳解iOS-按鈕單選與多選邏輯處理
- iOS應(yīng)用開發(fā)中導(dǎo)航欄按鈕UIBarButtonItem的添加教程
- 學(xué)習(xí)iOS開關(guān)按鈕UISwitch控件
- iOS 防止按鈕多次點(diǎn)擊造成多次響應(yīng)的方法
- iOS實(shí)現(xiàn)全局懸浮按鈕
相關(guān)文章
iOS常見算法以及應(yīng)用知識點(diǎn)總結(jié)
在本篇文章里小編給大家分享的是關(guān)于iOS常見算法以及應(yīng)用知識點(diǎn)總結(jié),有興趣的朋友們學(xué)習(xí)下。2019-10-10IOS如何在Host App 與 App Extension 之間發(fā)送通知
這篇文章主要介紹了IOS如何在Host App 與 App Extension 之間發(fā)送通知 的相關(guān)資料,需要的朋友可以參考下2016-03-03iOS開發(fā)檢測是否開啟定位、是否允許消息推送等權(quán)限的實(shí)例
下面小編就為大家分享一篇iOS開發(fā)檢測是否開啟定位、是否允許消息推送等權(quán)限的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01iOS給border設(shè)置漸變色的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于iOS給border設(shè)置漸變色的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03iOS11 WKWebView 無法加載內(nèi)容的解決方法
這篇文章主要介紹了iOS11 WKWebView 無法加載內(nèi)容,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11iOS應(yīng)用開發(fā)中StoryBoard搭建UI界面的基本使用講解
這篇文章主要介紹了iOS應(yīng)用開發(fā)中StoryBoard搭建UI界面的基本使用,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2016-02-02IOS開發(fā) UIAlertController詳解及實(shí)例代碼
這篇文章主要介紹了 IOS開發(fā) UIAlertController詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-12-12UIMenuController在Cell內(nèi)部無法顯示的解決辦法(iOS9.2)
這篇文章主要為大家詳細(xì)介紹了UIMenuController在Cell內(nèi)部無法顯示的解決辦法,感興趣的小伙伴們可以參考一下2016-08-08