关于左滑删除这块,相信不少朋友都遇到过。UITableView自定一个左滑的按钮可以自定义,但是越来越多的需求左滑时要实现多个功能。iOS8之后系统实现了左滑自定多个实现的功能。
很简单,首先需要创建一个UITableView.
UITableView *table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; table.delegate = self; table.dataSource = self; table.tableFooterView = [[UIView alloc] init]; self.tableView = table; [self.view addSubview:_tableView];
数据源可以随意添加一个,此处我用一个双重for循环,模拟出不同的人名和人的编号,并用懒加载的方式放到数据源数组中。
#pragma mark 懒加载数据 - (NSMutableArray *)dataArray { if (_dataArray == nil) { _dataArray = @[].mutableCopy; NSArray *lastNames = @[@"赵", @"钱", @"孙", @"李"]; NSArray *firstNames = @[@"虎",@"龙",@"狼",@"豹",@"蛇"]; //双重循环创建对象 for (int i = 0; i < lastNames.count; i++) { for (int j = 0; j < firstNames.count; j++) { NSString *name = [NSString stringWithFormat:@"%@%@", lastNames[i], firstNames[j]]; int ID = i * (int)lastNames.count + j; TyunModel *model = [[TyunModel alloc] initWithName:name ID:ID]; [_dataArray addObject:model]; } } } return _dataArray; }简单实现一个tableview之后效果如下图
此时左右滑动是没有任何作用的,关键方法就在实现UITableViewDeledate里面的方法,该方法iOS8之后才有。(若要兼容7之前,推荐一个库MGSwipeTableCell)
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath举一个简单例子,我定义三个按钮,实现删除、置顶和重编辑人物姓名。创建代码和效果图如下:
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { //添加一个删除按钮 UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) { }]; //添加一个置顶按钮 UITableViewRowAction *topAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"置顶" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) { }]; topAction.backgroundColor = [UIColor blueColor]; //添加一个编辑按钮 UITableViewRowAction *editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"修改" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) { }]; editAction.backgroundColor = [UIColor greenColor]; return @[deleteAction, topAction, editAction]; }
关于三个功能的实现,需要注意的是,所有关于tableview的操作如果影响到了页面cell的显示,通通遵循一个原则,就是先改数据,后变UI。另外关于置顶,不能单纯交换需要置顶项和第一项的数据;而是将需要置顶项插入到最前面。然后弹窗输入信息修改人物名字这块,简单示范了一下iOS9之后才出的UIAlertController的用法。此处有一个小细节就是点击了置顶之后,理想状态是该项移动到顶部之后滑出的菜单自动收回,之前没注意用的GCD延时利用[tableview reloadData],但是显示不太友好,可以在置顶操作之后加上[tableview setEditing:NO]; 完整实现代码
#pragma Mark 左滑按钮 iOS8以上 - (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { //添加一个删除按钮 UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) { //先删数据 再删UI [self.dataArray removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; }]; //添加一个置顶按钮 UITableViewRowAction *topAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"置顶" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) { // [self.dataArray exchangeObjectAtIndex:0 withObjectAtIndex:indexPath.row]; TyunModel *model = self.dataArray[indexPath.row]; [self.dataArray removeObjectAtIndex:indexPath.row]; [self.dataArray insertObject:model atIndex:0]; [tableView moveRowAtIndexPath:indexPath toIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // // [tableView reloadData]; // }); [tableView setEditing:NO]; }]; topAction.backgroundColor = [UIColor blueColor]; //添加一个编辑按钮 UITableViewRowAction *editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"修改" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) { TyunModel *model = self.dataArray[indexPath.row]; //弹窗输入名字 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"修改" message:@"请输入新名字" preferredStyle:UIAlertControllerStyleAlert]; [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.placeholder = @"此处输入名字"; textField.clearButtonMode = UITextFieldViewModeWhileEditing; textField.borderStyle = UITextBorderStyleRoundedRect; }]; [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { [tableView setEditing:NO]; }]]; [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { UITextField *textfield = alert.textFields.firstObject; NSString *newName = textfield.text; if (newName == nil) { newName = @""; } model.name = newName; [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; }]]; [self presentViewController:alert animated:YES completion:nil]; }]; editAction.backgroundColor = [UIColor greenColor]; return @[deleteAction, topAction, editAction]; }
至此,全部功能实现。另外有一个小彩蛋就是tableview 每个cell的分割线其实是可以调整长度的。比如说让线条从最左边到最右边
#pragma 设置线条画满 - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if ([cell respondsToSelector:@selector(setSeparatorInset:)]) { [cell setSeparatorInset:UIEdgeInsetsZero]; } if ([cell respondsToSelector:@selector(setLayoutMargins:)]) { [cell setLayoutMargins:UIEdgeInsetsZero]; } }
******以上
(欢迎随手给一颗星星哦~)本篇博客Demo地址https://github.com/xmy0010/DemoForCSDN
本人邮箱[email protected]欢迎小伙伴一起讨论,学习,进步。