在开发中常常会有对TableViewCell编辑操作的需求,比如点击某个按钮,让cell处于编辑状态;还有向左滑动时,cell右侧出现相应按钮可对cell进行相应编辑。例如qq的好友列表,长按可以对好友列表进行分组管理,可以新增分组、删除已有分组、对分组进行移动排序等。
一、系统方式实现简单的删除、插入、移动
实现三个方法即可实现上图效果:
1.获取编辑样式
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCellEditingStyle编辑样式枚举有三种,当然可以进行位运算组合
typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) {
UITableViewCellEditingStyleNone,
UITableViewCellEditingStyleDelete,
UITableViewCellEditingStyleInsert
};
说明
UITableViewCellEditingStyleNone 没有编辑样式
UITableViewCellEditingStyleDelete 删除样式
UITableViewCellEditingStyleInsert 插入样式
UITableViewCellEditingStyleInsert | UITableViewCellEditingStyleDelete 多选模式
2.提交编辑,在这个方法根据相应的编辑样式,进行相应的数据、UI处理
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
3.当cell处于编辑状态下时,是不能移动的,需实现这个方法,才能实现拖动Cell进行移动,
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
4、特别说明:如果需要当Cell处于编辑状态下时,Cell可以进行拖动移动、Cell不会缩进且左侧没有插入或删除按钮。则编辑状态选择应UITableViewCellEditingStyleNone,且实现下面这个方法
//处于编辑状态下,cell是否缩进 编辑样式是UITableViewCellEditingStyleNone才有效
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
二、左滑cell右侧实现多个按钮
1、在iOS8.0之前,要实现这样的效果图,是需要自定义的,系统并未提供相关的API。在iOS8.0系统提供了一个这样的API:
//左滑右侧添加多个按钮iOS8.0出的API
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
该方法返回一个UITableViewRowAction类型的数组,系统提供了两种按钮样式
- UITableViewRowActionStyleNormal 灰底白字
- UITableViewRowActionStyleDestructive 红底白字
没有提供有字体大小及颜色的自定义,但可以修改背景色,使用backgroundColor来进行设置。要想自定义只能采用别的方式,下面会介绍
2、在iOS11.0系统还提供一个新的API
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
比上面那个就多了一个图片的设置,但图片会被系统渲染成白色的。只有当cell达到一定得高度时,图片和文字才会一起显示,否则只会显示图片,不会显示文字
具体实现
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIContextualAction *collectAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal title:@"收藏" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
[self.dataSurces insertObject:@"我是新添加的" atIndex:indexPath.row];
[tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
completionHandler(YES);
}];
collectAction.image = [UIImage imageNamed:@"collect_icon"];
// collectAction.backgroundColor = [UIColor greenColor];
UIContextualAction *deleteAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"删除" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
[self.dataSurces removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
completionHandler(YES);
}];
//设置了图片,图片会被系统渲染成白色的
deleteAction.image = [UIImage imageNamed:@"delete_icon"];
return [UISwipeActionsConfiguration configurationWithActions:@[deleteAction,collectAction]];
}
这种方式有个缺点就是,图片都被渲染成了白色的了,可能有时这并不是需求想要的,那怎么办呢?需求虐我千百遍,我待需求如初恋。没关系下面我们就来看怎么去自定义
三、自定义左滑cell右侧实现多个按钮
先上张效果图
其实很简单的,只需要先用iOS8.0提供的API来实现多按钮,然后在去 API
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
重写即可,具体实现
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
for (UIView *subview in tableView.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:@"UISwipeActionPullView"]) {
if ([NSStringFromClass([subview.subviews[0] class]) isEqualToString:@"UISwipeActionStandardButton"]) {
UIButton *collectBtn = subview.subviews[0];
collectBtn.backgroundColor = [UIColor greenColor];
[collectBtn setImage:[UIImage imageNamed:@"collect_icon"] forState:UIControlStateNormal];
[collectBtn setTitle:@"插入" forState:UIControlStateNormal];
UIButton *deleteBtn = subview.subviews[1];
[deleteBtn setImage:[UIImage imageNamed:@"delete_icon"] forState:UIControlStateNormal];
[deleteBtn setTitle:@"删除" forState:UIControlStateNormal];
}
}
}
}
简单吧