(void)tableView:(UITableView*)aTableView
commitEditingStyle:
(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
NSDictionary *section = [data objectAtIndex:indexPath.section];
if (section)
{
NSMutableArray *content = [sectionvalueForKey:@”content”];
if (content && indexPath.row < [contentcount])
{
[contentremoveObjectAtIndex:indexPath.row];
}
}
[tableViewdeleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle ==UITableViewCellEditingStyleInsert)
{
NSDictionary *section = [dataobjectAtIndex:indexPath.section];
if (section) {
// Make a local reference to theediting view controller.
EditingViewController *controller =self.editingViewController;
NSMutableArray *content = [sectionvalueForKey:@”content”];
// A “nil” editingItemindicates the editor should create a new item.
controller.editingItem = nil;
// The group to which the new itemshould be added.
controller.editingContent =content;
controller.sectionName = [sectionvalueForKey:@”name”];
controller.editingTypes = [sectionvalueForKey:@”types”];
[self.navigationControllerpushViewController:controller animated:YES];
}
}
}
UITableView除了常规的选择模式(selection mode)外还有一个
编辑模式
(editing mode)
,在编辑模式中可
实现删除,插入,多选,重排序
等。
一
.
进入编辑模式
通过直接设置UITableView的editing属性或向其发送setEditing:animated:消息,可将其置于编辑模式。
self.tableview.editing= YES;
[self.tableviewsetEditing: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)editinganimated:(BOOL)animated
{
[super setEditing:editinganimated:animated];
[self.tableView setEditing:editinganimated:animated];
}
也可自定义其他按钮,将其响应设为修改tableView进入编辑模式。
-(void)editAction:(id)sender
{
[self.tableView setEditing:YESanimated: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 *)tableVieweditingStyleForRowAtIndexPath:(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)editingStyleforRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle ==UITableViewCellEditingStyleDelete)
{
[dataArrayremoveObjectAtIndex:indexPath.row];
[tableviewdeleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationFade];
}else if(editingStyle ==UITableViewCellEditingStyleInsert)
{
[dataArray insertObject:@”newItem” atIndex:indexPath.row];
[tableviewinsertRowsAtIndexPaths:[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 *)tableViewtargetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPathtoProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (proposedDestinationIndexPath.row == 5){
return [NSIndexPath indexPathForRow:8inSection:0];
}
return proposedDestinationIndexPath;
}
tableView向其DataSource发送tableView:moveRowAtIndexPath:toIndexPath:消息,在此方法中更改tableView的数据模型,移动里面数据项的位置。
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPathtoIndexPath:(NSIndexPath *)destinationIndexPath{
if(sourceIndexPath == destinationIndexPath)
return;
id object = [dataArrayobjectAtIndex:sourceIndexPath.row];
[dataArrayremoveObjectAtIndex:sourceIndexPath.row];
[dataArray insertObject:objectatIndex: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 swipingon 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 rowselection and editing in a UITableView
参考:
Table ViewProgramming Guide for iOS – Inserting and Deleting Rows and Sections
Table ViewProgramming Guide for iOS – Managing the Reordering of Rows
UITableView ClassReference
UITableViewDelegateProtocol Reference
UITableViewDataSourceProtocol Reference
UITableViewCellClass Reference
How does theTwitter 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 ViewMulti-Row Edit Mode
Multiple rowselection and editing in a UITableView
http://www.winddisk.com/2012/07/05/uitableview_edit_mod/原文地址