屬性方法
@property (nonatomic, getter=isEditing) BOOL editing;
// 默認狀態是非編輯狀態,如果不調用下面接口直接設置,是沒有動畫的
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;
DataSource
// 當增減按鈕按下時,用來處理數據和UI的回調。
// 8.0版本後加入的UITableViewRowAction不在這個回調的控制範圍內,UITableViewRowAction有單獨的回調Block。
- (void)tableView:(UITableView *)?tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
// 這個回調實現了以後,就會出現更換位置的按鈕,回調本身用來處理更換位置後的數據交換。
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
// 這個回調決定了在當前indexPath的Cell是否可以編輯。
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
// 這個回調決定了在當前indexPath的Cell是否可以移動。
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
Delegate
// 這個回調很關鍵,返回Cell的編輯樣式。
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
// 刪除按鈕的文字
- (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;
// 8.0後側滑菜單的新接口,支持多個側滑按鈕。
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;
// 這個接口決定編輯狀態下的Cell是否需要縮進。
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath;
// 這是兩個狀態回調
- (void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath __TVOS_PROHIBITED;
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath __TVOS_PROHIBITED;
編輯狀態
UITableView通過editing屬性控制編輯狀態,調用- (void)setEditing:(BOOL)editing animated:(BOOL)animated接口,可以決定是否使用原生的變換動畫。
當調用這個接口,並將editing設為YES是,UITableView將開始詢問代理(Delegate)需要編輯哪些Cell,用什麽樣的方式編輯。
首先調用回調方法- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;,這裏需要返回YES;
然後依次為各個Cell調用- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;方法獲取編輯樣式。
typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) {
UITableViewCellEditingStyleNone,
UITableViewCellEditingStyleDelete,
UITableViewCellEditingStyleInsert
};
編輯樣式枚舉有三種,位運算組合則由不同的用途。
UITableViewCellEditingStyleNone 沒有編輯樣式
UITableViewCellEditingStyleDelete 刪除樣式 (左邊是紅色減號)
UITableViewCellEditingStyleInsert 插入樣式 (左邊是綠色加號)
UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleInsert 多選模式,左邊是藍色對號
特別註意,右邊的移動並不是這裏控制的,需要實現下面這個回調才會出現。
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
另外對於新手來說,要明白這裏的回調都沒有對UI和數據進行操作,開發者需要在回調中,完成相應的操作。比如刪除或者添加壹條數據,應在
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
上面這個回調中,根據editingStyle進行判斷,處理對應的UI和數據。
數據與UI更新
數據更新沒什麽好說的,直接操作數據容器就好,無論是數組、字典還是CoreData數據。UI更新則需要使用TableView的方法,如果需求reloadData無法滿足,則必須使用下面的方法
- (void)beginUpdates; // allow multiple insert/delete of rows and sections to be animated simultaneously. Nestable
- (void)endUpdates; // only call insert/delete/reload calls or change the editing state inside an update block. otherwise things like row count, etc. may be invalid.
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection NS_AVAILABLE_IOS(5_0);
- (void)insertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- (void)deleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath NS_AVAILABLE_IOS(5_0);
beginUpdates和endUpdates兩個方法,在妳需要批量處理Cell的時候,用來包裹住妳的處理代碼,其他方法名字都很直觀,不壹壹介紹了。