UITableView除了常规的选择模式(selection mode)外还有一个编辑模式(editing mode),在编辑模式中可实现删除,插入,多选,重排序等。
一.进入编辑模式
self.tableview.editing = YES; [self.tableview setEditing:YES animated:YES];


可利用此按钮在设置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]; }
- (void)editAction:(id)sender { [self.tableView setEditing:YES animated:YES]; }
UITableView接收到setEditing:animated:消息时,会发送同样的消息到所有可见的cell,设置其编辑模式。
二.插入和删除
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 1) { return NO; } return YES; }
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewCellEditingStyleDelete; //return UITableViewCellEditingStyleInsert; }
当返回的是UITableViewCellEditingStyleDelete时,所有可编辑的Cell左侧都会显示红色的”减号”标示;
点击左边的“减号”,减号会旋转90度变竖形,并且cell右侧出现”Delete”按钮。
当返回的是UITableViewCellEditingStyleInsert时,在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收到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

五.多行选取模式
在iphone自带的邮件程序中,点击编辑按钮后会出现使用”红勾”多选的效果,如图所示
有几种方法可以实现这种效果
1.苹果公共API

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
UITableView Class Reference
UITableViewDelegate
Protocol Reference
UITableViewDataSource
Protocol Reference
UITableViewCell Class Reference
How does the Twitter iPhone app implement side
swiping on a table?
UITableView划动删除的实现
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