iOS基础学无止境iOS开发

UITableView 编辑总结

2016-10-17  本文已影响1397人  酒茶白开水

代码下载地址一
代码下载地址二

一、总述

在iOS开发中,UITableView的使用率可以说是非常高的,所以它在iOS开发中的地位是无法替代的。最近项目涉及到UITableView的编辑问题,这个问题其实非常广泛,我希望从我的角度尽可能地把这个问题思虑全面,讲述清楚。

UITableView的编辑,我主要从这些方面来讲述:cell的插入,删除,选择,移动排序以及UITableView的编辑模式等。

二、UITableView cell的插入

UITableView cell的插入首先要保证UITableView的数据源插入了数据,否则会发生奔溃。正确地插入了数据之后,可以通过一下几种方式达到插入Cell的效果:

1.刷新UITableView,既调用UITableView的-reloadData:方法或者-reloadSections: withRowAnimation:方法,其实还有其他的一些刷新UITableView的方式。但是我要说的是使用这种方式的话性能方面不是很好,因为刷新UITableView会调用很多次代理方法。

2.直接插入Cell,既调用UITableView的insertRowsAtIndexPaths:withRowAnimation:方法或者insertSections: withRowAnimation:方法来插入。这种方式相对性能较高。

需要注意的问题:插入了Cell最好还是调用一下UITableView的-scrollToRowAtIndexPath:atScrollPosition:UITableViewScrollPositionNoneanimated:这个方法,把UITableView滚动到对应的位置。

代码展示:

NSInteger row = self.dataArr.count - 1;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
        
 //UITableView 滚动到添加的行
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.dataArr.count - 1 inSection:0] atScrollPosition:UITableViewScrollPositionNone animated:YES];

二、UITableView cell的删除

UITableView 的cell删除的效果如下:
![Uploading Simulator Screen Shot 2016年10月14日 下午5.55.04_184090.png . . .]](https://img.haomeiwen.com/i3238517/72ec984109d01951.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

Simulator Screen Shot 2016年10月14日 下午5.55.04.png
Simulator Screen Shot 2016年10月14日 下午5.55.05.png

UITableView 的cell删除的步骤如下:
1.在UITableView的- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath这个代理方法中返回YES,来确定UITableView能够被编辑。
2.在UITableView的- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath这个代理方法中根据编辑的类型移除掉相应的数据,然后调用- (void)deleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation或者- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation这个方法来删除Cell。
提示:可以在- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath这个代理方法中设置删除按钮的文字,否则默认为delete。

代码展示:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"删除";
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [self.dataArr removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
    }
    else if (editingStyle == UITableViewCellEditingStyleInsert)
    {
        
    }
    else
    {
        
    }
}

UITableView的编辑模式

设置UITableView的editing属性为YES可以进入编辑模式,UITableView的编辑模式有几种状态,在UITableView的- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath这个代理方法中设置,可以返回一下几种状态:

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    switch (indexPath.row%4) {
        case 0:
            return UITableViewCellEditingStyleNone;
            break;
        case 1:
            return UITableViewCellEditingStyleDelete;
            break;
        case 2:
            return UITableViewCellEditingStyleInsert;
            break;
            
        default:
            return UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleInsert;
            break;
    }
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleNone) {
        
    }
    else if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        
    }
    else if (editingStyle == UITableViewCellEditingStyleInsert)
    {
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"添加计划" message:@"请输入明日计划" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
        [alertController addAction:cancelAction];
        [self presentViewController:alertController animated:YES completion:nil];
    }
    else
    {
        
    }
}

UITableView cell的选择

Simulator Screen Shot 2016年10月16日 下午5.52.58.png Simulator Screen Shot 2016年10月16日 下午5.53.00.png

UITableView cell的选择,我们只需要如下几步操作即可:
1.进入编辑模式(前面已经讲过)
self.tableView.editing = YES;
2.在UITableView的- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath这个代理方法中设置编辑模式为选择的类型

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    /*
     UITableView 编辑状态的样式有如下三种:
        UITableViewCellEditingStyleNone:cell往右缩进,但是左边不出现任何控件
        UITableViewCellEditingStyleDelete:cell往右缩进,但是左边出现红色减号控件
        UITableViewCellEditingStyleInsert:cell往右缩进,但是左边出现蓝色加号控件
        UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleInsert:cell往右缩进,但是左边出现选择控件
     */
        return UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleInsert;
  }

3.在UITableView的- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath和

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (!tableView.editing) {
        [tableView deselectRowAtIndexPath:indexPath animated:YES];
    }
    else
    {
        [self.selectedDataArr addObject:self.dataArr[indexPath.row]];
    }
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (tableView.editing) {
        [self.selectedDataArr removeObject:self.dataArr[indexPath.row]];
    }
}

4.完成选择后的操作,这主要根据需求而定,我在这里做了一个删除操作

            //插入数据,刷新界面
            NSMutableArray *deleteArr = [NSMutableArray arrayWithCapacity:1];
            NSIndexPath *deleteIndexPath = nil;
            for (NSString *str in self.selectedDataArr) {
                deleteIndexPath = [NSIndexPath indexPathForRow:[self.dataArr indexOfObject:str] inSection:0];
                [deleteArr addObject:deleteIndexPath];
            }
            [self.dataArr removeObjectsInArray:self.selectedDataArr];
            [self.selectedDataArr removeAllObjects];
            [self.tableView deleteRowsAtIndexPaths:deleteArr withRowAnimation:UITableViewRowAnimationNone];

UITableView cell的移动排序

Simulator Screen Shot 2016年10月16日 下午5.55.06.png Simulator Screen Shot 2016年10月16日 下午5.55.22.png

UITableView cell的排序操作其实和选择操作非常类似,首先也是进入编辑模式,然后在UITableView的- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath的这个代理方法中返回YES,让UITableView可以移动,最后在UITableView的- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath这个代理方法中对排序之后的数据进行操作即可

//设置tableView编辑状态
self.tableView.editing = YES;

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    NSString *exchangeStr = self.dataArr[sourceIndexPath.row];
    [self.dataArr removeObjectAtIndex:sourceIndexPath.row];
    [self.dataArr insertObject:exchangeStr atIndex:destinationIndexPath.row];
}

UITableView 右滑cell出现多个按钮

Simulator Screen Shot 2016年10月16日 下午11.46.10.png

UITableView 右滑cell出现多个按钮在iOS8之前是不支持的,需要自己去实现,在iOS8以后,UITableView的代理中多了这样一个方法- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath和这样一个类UITableViewRowAction,一个UITableViewRowAction对象表示一个按钮,按钮的点击操作包装在UITableViewRowAction创建方法的block中,在代理方法中返回UITableViewRowAction的数组就可以了,最先放入数组的按钮显示在最右侧,最后放入的显示在最左侧。

- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //添加一个删除按钮
    UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        //处理数据
        [self.dataArr removeObjectAtIndex:indexPath.row];
        //更新UI
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
    }];
    
    //添加一个上移按钮
    UITableViewRowAction *upAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"上移" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        if (indexPath.row > 0) {
            //处理数据
            [self.dataArr exchangeObjectAtIndex:indexPath.row withObjectAtIndex:indexPath.row - 1];
            //更新UI
            [tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section]] withRowAnimation:UITableViewRowAnimationNone];
            [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
        }
    }];
    
    //添加一个下移按钮
    UITableViewRowAction *downAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"下移" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        if (indexPath.row < self.dataArr.count - 1) {
            [self.dataArr exchangeObjectAtIndex:indexPath.row withObjectAtIndex:indexPath.row + 1];
            //更新UI
            [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
            [tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:indexPath.row + 1 inSection:indexPath.section]] withRowAnimation:UITableViewRowAnimationNone];
        }
    }];
    
    //设置背景颜色
    downAction.backgroundColor = [UIColor colorWithRed:(arc4random()%256)/255.0 green:(arc4random()%256)/255.0 blue:(arc4random()%256)/255.0 alpha:1];
    
    //放回数组返回
    return @[deleteAction, upAction, downAction];
}

需要注意的是:如果我们自己使用UITableViewRowAction设定了一个或多个按钮,系统自带的删除按钮就失效了。

上一篇下一篇

猜你喜欢

热点阅读