首先我們來了解iOS的單行刪除:
在 tableView 中有時候我們會對其進行增刪操作,主要是使用系統(tǒng)的,而不是自定義的.
對于系統(tǒng)的可編輯狀態(tài)我們可以看到有三種:
UITableViewCellEditingStyleNone,
UITableViewCellEditingStyleDelete,
UITableViewCellEditingStyleInsert



接著我們再來了解iOS的多行操作;比如下面的圖所示:

如果UI不是大變動這時候沒必要自定義了.其實這個系統(tǒng)也是給寫好的.而且對于 cell 的循環(huán)利用問題已經(jīng)做過處理了.
下面看一下重點,實現(xiàn)這個多選有兩種方法:
1>使用 tableView 的屬性:
@property (nonatomic) BOOL allowsMultipleSelectionDuringEditing
allowsMultipleSelectionDuringEditing這個屬性默認是 NO, 設置成 YES. 就是出現(xiàn)多選.
2>使用 tableView 的代理方法.我們知道上面代理只有三個選項,沒有多選的枚舉值.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
// 當我們 使用兩個枚舉值的按位或時,就會發(fā)現(xiàn)多選出現(xiàn)了.
return UITableViewCellEditingStyleDelete | UITableViewCellEditingStyleInsert;
}
當然如果需要這種效果,不要忘記設置為可編輯[self setEditing:YES animated:YES];
注意:如果需要自定義多選效果的話,一定要在數(shù)據(jù)模型中定義是否選中狀態(tài),否則 cell 循環(huán)利用,會使得選中的行有問題. 刪數(shù)據(jù)時要注意的是刪除相應數(shù)據(jù)后, 重新刷新一下表格.刪除的數(shù)據(jù),和刪除的表格一定要對應起來.
1> 左滑出現(xiàn)刪除按鈕
// 1.確保cell 可以被編輯
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
// 2.左滑后點擊 delete 之后,會調用下面的方法,
// PS:這個方法必須寫, 否則UITableViewRowAction 在ios9中正常 在ios8中無法滑動
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%@", indexPath);
}
// 注意:這個方法可以不去寫,如果寫了必須 return 的是UITableViewCellEditingStyleDelete,否則不會出現(xiàn)側滑效果
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
// 3.如果希望修改標題的話.
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {// 測試用
return @"haha";
}

由于現(xiàn)在越來越多的新需求產(chǎn)生,很多時候我們側滑會出多個選項.從 iOS 以后,蘋果也有了相應的方法:
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
// 使用 Block 回調,實現(xiàn)點擊后的方法
UITableViewRowAction *action = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"增加" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
NSLog(@"%@", indexPath);
}];
UITableViewRowAction *action1 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"減少" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
NSLog(@"%@", indexPath);
}];
// 蘋果的習慣,右側的多個按鈕,顯示位置是反著的
return @[action, action1];
}

現(xiàn)在下面是自定義實現(xiàn) 多行刪除 的部分代碼:
// 消息列表數(shù)組
@property (nonatomic, strong) NSMutableArray *messageList;
// 編輯按鈕
@property (nonatomic, weak) UIButton *editBtn;
// 多選數(shù)組
@property (nonatomic, strong) NSMutableArray *selectedEditList;
// 消息主鍵
@property (nonatomic, copy) NSString *pushId;
#pragma mark - 懶加載
- (NSMutableArray *)messageList {
if (!_messageList) {
_messageList = [NSMutableArray array];
}
return _messageList;
}
- (NSMutableArray *)selectedEditList {
if (!_selectedEditList) {
_selectedEditList = [NSMutableArray array];
}
return _selectedEditList;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = QTXBackgroundColor;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
// 隱藏無數(shù)據(jù)的cell
self.tableView.tableFooterView = [[UIView alloc] init];
self.navigationItem.title = @"系統(tǒng)消息";
// 編輯按鈕
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn addTarget:self action:@selector(editClick:) forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:@"編輯" forState:UIControlStateNormal];
[btn setTitle:@"取消" forState:UIControlStateSelected];
[btn setTitleColor:QTXNavTitleColor forState:UIControlStateNormal];
btn.titleLabel.font = [UIFont systemFontOfSize:14];
// 讓按鈕內部的所以內容右對齊
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
btn.size = CGSizeMake(44, 44);
self.editBtn = btn;
UIBarButtonItem *editItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
self.navigationItem.rightBarButtonItem = editItem;
}
- (void)editClick:(UIButton *)btn {
btn.selected = !btn.selected;
if (btn.selected) {
self.deleteView.hidden = NO;
for (QTXSystemMessageModel *model in self.messageList) {
model.edit = YES;
model.checked = NO; // 選中編輯狀態(tài)時 默認都是未選中
}
} else {
self.deleteView.hidden = YES;
[self.selectedEditList removeAllObjects];
for (QTXSystemMessageModel *model in self.messageList) {
model.edit = NO;
}
}
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.messageList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
QTXSystemMessageListCell *cell =[QTXSystemMessageListCell cellWithTableView:tableView];
if (self.messageList.count) {
QTXSystemMessageModel *model = self.messageList[indexPath.row];
cell.model = model;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
QTXSystemMessageModel *model = self.messageList[indexPath.row];
return model.cellH; // 自適應消息內容高度
}
#pragma mark - UITableViewDelegate
// 選中當前行已讀
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
QTXSystemMessageModel *model = self.messageList[indexPath.row];
// 編輯狀態(tài) 點擊事件
if (self.editBtn.selected) {
model.checked = !model.isChecked;
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
if (model.isChecked) {
[self.selectedEditList addObject:model];
} else {
[self.selectedEditList removeObject:model];
}
} else {
// 取出模型判斷是否已讀,1)已讀直接return,
if ([model.pushStatus isEqualToString:@"1"]) return;
#warning todo :
// 2) 未讀點擊選中發(fā)送請求修改狀態(tài)已讀
}
}
//先要設置Cell可編輯
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
//定義編輯樣式
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
//進入編輯模式,按下出現(xiàn)的編輯按鈕后 編輯狀態(tài)刪除
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
QTXSystemMessageModel *model = self.messageList[indexPath.row];
[self uploadDeleteData:model.pushId reloadData:indexPath];
}
- (void)uploadDeleteData:(NSString *)pushId reloadData:(NSIndexPath *)indexPath {
#warning todo :
// 1.發(fā)送刪除請求
// 2.刪除成功后記得 移除當前模型的數(shù)據(jù) 和相對應的數(shù)據(jù)源cell
/*
if (indexPath) {
[weakSelf.messageList removeObjectAtIndex:indexPath.row]; // 移除當前模型的數(shù)據(jù)
[weakSelf.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight]; // 移除當前相應的數(shù)據(jù)源cell
}
[weakSelf.tableView reloadData];
*/
}
// 在請求消息數(shù)據(jù)方法里需要加載調用這個方法
/*
// 當前系統(tǒng)消息列表
NSArray *currentPageArray = [QTXSystemMessageModel loadSystemMessageFromJson:json[@"data"]];
[self currentEditStatus:currentPageArray];
// 所有系統(tǒng)消息列表
[weakSelf.messageList addObjectsFromArray:currentPageArray];
*/
- (void)currentEditStatus: (NSArray *)currentPageArray {
if (self.editBtn.selected) {
for (QTXSystemMessageModel *model in currentPageArray) {
model.edit = YES;
}
} else {
for (QTXSystemMessageModel *model in currentPageArray) {
model.edit = NO;
}
}
}
// 點擊刪除事件
- (void)deleteBtnClick {
for (QTXSystemMessageModel *model in self.selectedEditList) {
[self uploadDeleteData:model.pushId reloadData:nil];
}
[self.messageList removeObjectsInArray:self.selectedEditList];
[self.tableView reloadData];
[self editClick:self.editBtn];
}
效果如下:

1.png

2.png