UITableView的代理方法,實現編輯、刪除、排序、多選
UITableView除了常規的選擇模式(selection mode)外還有一個編輯模式(editing mode),在編輯模式中可實現刪除,插入,多選,重排序等。
一.進入編輯模式
通過直接設定UITableView的editing屬性或向其傳送setEditing:animated:訊息,可將其置於編輯模式。
self.tableview.editing = YES; [self.tableview setEditing:YES animated:YES];
UIViewController本身也有editing屬性和setEditing:animated:方法,在當前檢視控制器由導航控制器控制且導航欄中包含editButtonItem時,若UIViewController的editing為NO,則顯示為”Edit”,若editing為YES,則顯示為”Done”。
可利用此按鈕在設定UIViewController的editing狀態時同時設定tableView的編輯狀態。
- (void)viewDidLoad { [super viewDidLoad]; ....
self.navigationItem.rightBarButtonItem = self.editButtonItem; }
-(void)setEditing:(BOOL)editing animated:(BOOL)animated { [super
setEditing:editing animated:animated]; [self.tableView
setEditing:editing animated:animated]; }
也可自定義其他按鈕,將其響應設為修改tableView進入編輯模式。
- (void)editAction:(id)sender { [self.tableView setEditing:YES animated:YES]; }
UITableView接收到setEditing:animated:訊息時,會傳送同樣的訊息到所有可見的cell,設定其編輯模式。
二.插入和刪除
進入編輯模式後,UITableView向其DataSource傳送tableView:canEditRowAtIndexPath:訊息詢問每個indexPath是否可編輯,在此方法中對不可以編輯的cell返回NO,可以編輯的cell返回YES,若全部可編輯,可不實現,大部分應用不實現此方法。
-(BOOL)tableView:(UITableView *)tableView
canEditRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row
== 1) { return NO; } return YES; }
然後,UITableView 向其delegate傳送tableView:editingStyleForRowAtIndexPath:訊息詢問EditingStyle,這裡返回刪除(UITableViewCellEditingStyleDelete)或者插入(UITableViewCellEditingStyleInsert);若不實現此方法,則預設為刪除模式,即UITableViewCellEditingStyleDelete。
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewCellEditingStyleDelete; //return UITableViewCellEditingStyleInsert; }
當返回的是UITableViewCellEditingStyleDelete時,所有可編輯的Cell左側都會顯示紅色的”減號”標示;
點選左邊的“減號”,減號會旋轉90度變豎形,並且cell右側出現”Delete”按鈕。
當返回的是UITableViewCellEditingStyleInsert時,在cell的左邊會顯示綠色”加號”按鈕。
當點選”Delete”按鈕或者”加號”按鈕時,UITableView向其DataSource傳送tableView:commitEditingStyle:forRowAtIndexPath:訊息,根據傳遞editingStyle來執行實際的刪除或插入操作,其流程是先修改tableView的資料模型,向其中刪除或插入對應資料項,然後再調整tableView的顯示,刪除或插入對應的cell。
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete)
{ [dataArray removeObjectAtIndex:indexPath.row];
[tableview deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade]; }else if(editingStyle == UITableViewCellEditingStyleInsert)
{ [dataArray insertObject:@"new Item"
atIndex:indexPath.row]; [tableview
insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade]; } }
當要刪除或插入section時,需呼叫deleteSections:withRowAnimation:或insertSections:withRowAnimation:方法。
插入刪除流程的方法呼叫時序如圖:
三.重排序
若當前tableView允許重排序,則會在每個cell的右側出現三條灰色橫線的控制元件,拖動此空間可將cell移動到不同的位置。重排序模式和刪除/插入是並行的,即可在顯示重排序空間的同時顯示刪除或插入控制元件。
當tableView的dataSource實現tableView:moveRowAtIndexPath:toIndexPath:方法後,tableView進入編輯模式後就會在右側顯示“重排序”控制元件,如圖所示。
其訊息處理流程為:
tableView收到setEditing:animated:訊息並將同樣的訊息傳送給可見的cell。
tableView向其DataSource傳送tableView:canMoveRowAtIndexPath:訊息,詢問每一行是否可顯示重排序空間,若為NO,則不顯示,若為YES則顯示。此方法不實現時預設所有行都可顯示重排序控制元件。這時就會在每一行的右側顯示重排序控制元件。
因為重排序沒有使用向delegate傳送tableView:editingStyleForRowAtIndexPath:訊息詢問編輯模式,所以其 與刪除、插入控制元件可同時存在,在一般情況下不應該同時出現,所以應實現了 tableView:editingStyleForRowAtIndexPath:並返回 UITableViewCellEditingStyleNone;若不實現 tableView:editingStyleForRowAtIndexPath:則會預設使用刪除模式,即右側出現“排序”控制元件時,左側會出現”刪 除”控制元件。
使用者可拖動每行右側的空間來移動該行的位置。
使用者拖動某行經過目標行上方時,tableView會向delegate傳送tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:(若delegate有實現)訊息詢問是否可移動到此位置(ProposedIndexPath),若不可移動到此位置則返回一個新的目的indexPath,可以的話直接將ProposedIndexPath返回即可。一般情況下不需實現此方法。
-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath { if (proposedDestinationIndexPath.row == 5) { return [NSIndexPath indexPathForRow:8 inSection:0]; } return proposedDestinationIndexPath; }
tableView向其DataSource傳送tableView:moveRowAtIndexPath:toIndexPath:訊息,在此方法中更改tableView的資料模型,移動裡面資料項的位置。
- (void)tableView:(UITableView *)tableView
moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toIndexPath:(NSIndexPath *)destinationIndexPath{ if(sourceIndexPath
== destinationIndexPath) return; id object = [dataArray
objectAtIndex:sourceIndexPath.row]; [dataArray
removeObjectAtIndex:sourceIndexPath.row]; [dataArray
insertObject:object atIndex:destinationIndexPath.row]; }
總體訊息流程為:
四.Swipe to Delete
當使用者在tableView的一行上滑動時,會在右側直接出現刪除按鈕,點選刪除按鈕可刪除此行。啟用Swipe to Delete模式的條件時tableView的DataSource實現了tableView:commitEditingStyle:forRowAtIndexPath:方法;在iOS5中還要保證tableView的allowsMultipleSelectionDuringEditing屬性不為YES(見後面解釋)。
滿足上述條件後,當使用者在tableView的行上滑動時,tableView會向自身傳送setEditing:animated:訊息進入編 輯模式,同時向可見的cell傳送setEditing:animated:訊息,在當前滑動的行右側會出現紅色”Delete”按鈕。
同樣在點選”Delete”按鈕時會向tableView的DataSource傳送tableView:commitEditingStyle:forRowAtIndexPath:訊息,執行實際的刪除操作。
“Delete”按鈕上顯示的文字可以更改,包括普通刪除模式下的”Delete”按鈕。若要顯示不同的內容,可在tableView Delegate中實現tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:方法,返回”Delete”按鈕中需要顯示的內容
tableView在向自身傳送setEditing:animated:訊息的前後,會向其delegate分別傳送tableView:willBeginEditingRowAtIndexPath:,tableView:didEndEditingRowAtIndexPath:訊息。在這些方法中可相應更新tableView的顯示。How does the Twitter iPhone app implement side swiping on a table?中通過實現tableView:willBeginEditingRowAtIndexPath:方法使得使用者在tableView的行上swipe時可滑出選單。
五.多行選取模式
在iphone自帶的郵件程式中,點選編輯按鈕後會出現使用”紅勾”多選的效果,如圖所示
有幾種方法可以實現這種效果
1.蘋果公共API
在iOS5.0中UITableView增加了allowsMultipleSelectionDuringEditing屬性和indexPathsForSelectedRows方 法,allowsMultipleSelectionDuringEditing屬性預設為NO,當此值為YES時,UITableView進入編輯模式 不會向dataSource查詢editStyle,而會直接每個Cell的左邊顯示圓形選擇框,點選選擇該行後圓形框裡面為對勾。可使用 indexPathsForSelectedRows方法獲取到所有選擇行的indexPath。
蘋果公司提供了使用此種方式的例項程式碼:TableMultiSelect
注:當allowsMultipleSelectionDuringEditing屬性為YES時,不管當前在不在編輯模式內,swipe to delete都不起作用,若要同時使用swipe to delete,需在完成選擇任務後,將tableView的allowsMultipleSelectionDuringEditing恢復為NO。另 外,多選”控制元件可與”重排序”控制元件同時出現。
2.蘋果私用API
在iOS5之前,蘋果並沒有提供多行選取的API,但其內部確實實現了,我們可以通過使用私有API實現。
在tableView:editingStyleForRowAtIndexPath:方 法中若返回的是 UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleInsert則可以進入 多選模式,效果同allowsMultipleSelectionDuringEditing設為YES時相同。這也是“多選”控制元件不會與“插入”控 件,”刪除”控制元件同時出現,卻可以和”重排序”控制元件同時存在的原因。
獲取到選擇的行時,同樣可以使用私有方法indexPathsForSelectedRows獲取,或者使用公開的tableView:didSelectRowAtIndexPath:,tableView:didDeselectRowAtIndexPath:方法在選擇/取消選擇時逐個獲取並儲存。
注:以上兩種方式均需保證UITableViewCell的selectionStyle屬性不為UITableViewCellSelectionStyleNone,否則選擇後的“紅勾”無法顯示。
3.完全定製方法
一些文章中介紹了不使用tableView本身的方法而完全自己定製實現多選效果的方法。
如:Table View Multi-Row Edit Mode
Multiple row selection and editing in a UITableView
參考:
Table View Programming Guide for iOS – Inserting and Deleting Rows and Sections
Table View Programming Guide for iOS – Managing the Reordering of Rows
UITableViewDelegate Protocol Reference
UITableViewDataSource Protocol Reference
UITableViewCell Class Reference
How does the Twitter iPhone app implement side swiping on a table?
UITableView多選刪除,類似mail中的多選刪除效果
iPhone開發技巧之私有API(2)— UITableView
iOS 5 Dev Warning: UITableView’s Multiple Select During Editing Doesn’t Work with Swipe to Delete
Table View Multi-Row Edit Mode
Multiple row selection and editing in a UITableView
http://linglong117.blog.163.com/blog/static/277145472012103075527791/
相關文章
- iOS使用UITableView實現的富文字編輯器iOSUIView
- 原生js多選框選中排序及刪除JS排序
- iOS 多選刪除(附tableViewTips及單選刪除)iOSView
- MyBatis-Plus之邏輯刪除的實現MyBatis
- win10怎麼刪除右鍵多餘選項 win10刪除右鍵多餘選項的方法Win10
- 列表頁取出刪除編輯功能
- 仿 iOS 列表的編輯功能 – 刪除篇iOS
- win10右鍵刪除“使用畫圖3d進行編輯”方法_win10如何刪除右鍵選單“使用畫圖3d進行編輯”選項Win103D
- ajax編輯資訊和刪除資訊
- javascript實現 checkbox全選和批量刪除功能JavaScript
- Linux 中刪除目錄的多種方法Linux
- 【演算法-初級-陣列】刪除排序陣列中的重複項(多語言版實現)演算法陣列排序
- ASP.NET - GridView實現點選編輯列ASP.NETView
- mySql刪除多個表 刪除多個欄位的SQLMySql
- Spring boot+Mybatisplus用AR模式實現邏輯刪除操作Spring BootMyBatis模式
- Laravel-admin 中列表中禁止某行編輯、刪除Laravel
- 介面測試平臺-66: 多介面用例實現之 小用例:新增+刪除+關閉+排序排序
- vue 工作專案中 實現訊息列表的 全選,反選,刪除功能Vue
- Jquery實現頁面的新增、刪除、全選、取消全選、漸變色jQuery
- 選擇排序(python)實現排序Python
- Java PDF書籤——新增、編輯、刪除、讀取書籤Java
- 多選操作的實現
- MybatisPlus - [05] 邏輯刪除MyBatis
- 誤刪除資料了怎麼辦?小編交易誤刪除資料的恢復方法
- 如何刪除多餘的win10管理員_win10刪除管理員賬戶的方法Win10
- 基於 SplPriorityQueue 實現的排序方法排序
- php實現 氣泡排序,插入排序,選擇排序PHP排序
- Windows10系統刪除混合現實門戶的方法【圖文】Windows
- 可以增刪和排序的下拉屬性實現排序
- Laravel 如何實現資料的軟刪除Laravel
- win10右鍵skydrive pro選項怎麼刪除_win10右鍵選單中skydrive pro選項的刪除方法Win10
- Java-二叉排序樹的刪除Java排序
- 刪除排序陣列中的重複項排序陣列
- RecyclerView 梳理:點選&長按事件、分割線、拖曳排序、滑動刪除View事件排序
- Laravel 模型實現連帶刪除Laravel模型
- 仿 iOS 列表的編輯功能 – 排序篇iOS排序
- Laravel 中利用『模型事件』來實現刪除資料時的連帶刪除Laravel模型事件
- vue對table的某一行的資料進行編輯,刪除操作Vue
- 選擇排序和插入排序(C++實現)排序C++