爬爬爬之路:UI(十) UITableView(二) UITableView编辑 UITableViewCell移动

UITableView编辑状态

UITableVIew编辑分为两种状态

  • 删除
  • 添加

UITableView添加和删除

对TableView进行编辑分为以下步骤

开启TableView的编辑状态

主要用到的方法:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;
在某个事件响应方法中利用tableView对象调用本方法开启tableView的编辑模式.
开启编辑模式后会自动调用与编辑有关的方法. 注意这些自动调用的方法是需要在ViewController.m中重写实现的.
一定允许编辑, 系统就会自动完成点击编辑左侧出现红色删除键, 点击后cell整体左滑漏出红色delete按键的动画 (默认是只有删除类型响应的)

允许某分区某行可以进行编辑 (不指定默认是都可以进入编辑状态)

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
可以指定某个分区的某一行是不可进行编辑的

指定编辑状态 (指定是删除还是添加状态)

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) {
    UITableViewCellEditingStyleNone,     无编辑类型
    UITableViewCellEditingStyleDelete,   删除类型
    UITableViewCellEditingStyleInsert    添加(插入)类型
};

可以同来指定某个分区的某行的编辑类型是编辑还是添加
若不指定, 默认都是删除类型

完成编辑(提交编辑)

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;

重写了本方法时, 可以自动实现按住cell左滑漏出右侧红色delete按键动画.
在实现本方法时, 应注意 要先删除对应数据, 再响应刷新界面方法.
第二个参数editingStyle是编辑的状态, 用于区别删除和添加两种编辑状态响应的不同的处理方式.
添加删除对应的刷新方法常用的有3种

  1. 全局刷新数据方法, 也是最为常用的方法
    - (void)reloadData;
    用法为 [table reloadData];
    reloadData可以刷新cell, Section headers和Section footers, indexPath数组等相关的数据
    reloadData刷新不带动画, 触发及刷新整个界面的可视相关部分

  2. 删除数据响应刷新界面方法

    - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

    第一个参数为被删除的数据所在的索引, 可以是一个数据, 也可以是多个数据. 第二个参数为删除数据时的动画效果
    用法为:

    // 之前必选先在数据源数据中将该数据删除
    [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:(UITableViewRowAnimationBottom)];

    本方法可以用于删除多个indexPath对应的cell. 注意的是, 在调用本方法之前必须已经将该数据从数组中删除. 否则再对界面进行操作的时候会导致崩溃.

  3. 添加数据响应的刷新界面方法

    - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
    

    用法同上

除了对当行增删的方法以外, 还有对分区进行增删的方法

- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;

第一个参数是要求传入一个存有需要删除的分区下标的集合对象, 第二个参数是删除时的动画
用法如下:

[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:(UITableViewRowAnimationFade)];

同样必须在对数据源进行对应数据的删除以后才可以实现本方法.
同理还有对分区进行添加的的方法

- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;

方法参照以上.


UITableViewCell的移动交换

除了增删, UITableView还可以响应它上面的cell位置互换

移动操作需要以下步骤

开启编辑状态

和增删操作的第一步一样, 当cell需要进行移动操作的时候需要先打开UITableView的编辑状态.
方法参照前文

允许某行某列移动 (默认是都可以移动)

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;

可以指定某行某列可以移动或者不可移动. 若不实现本方法则是默认都可以移动的.

完成交换操作

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;

但重写了本方法时, 编辑状态下, cell的右侧会出现可移动标志 样式的图案.
第二个参数 sourceIndexPath 为选中的cell初始的索引 (长按图标处使cell发生悬空动画的起始索引处).
第三个参数 destinationIndexPath 为选中cell放下的位置(目标位置)的索引.

需要注意的是, 从移动完成的结果可区分同分区交换(移动) 和跨分区交换(移动), 可以通过sourceIndexPath和destinationIndexPath的Section是否相同进行判断是否是同分区操作
同区交换的时候, 需要对当前分区的数据源数组进行操作(通常用可变数组接受分区的元素).

  1. 先将目标cell从原位置删除(sourceIndexPath)
  2. 将目标cell插入目的地位置(destinationIndexPath)

MRC模式下, 此处注意在删除前需要对Model先进行一次retain操作. 再在insert操作结束用release.

对于跨区移动, 为了保证界面的基本逻辑性不变, 通常是禁止跨区交换的.

禁止跨区交换所使用的方法:

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;

第二个参数 同上, 代表来源索引 第三个参数表示建议的目的地索引
用法如下:

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
    // 判断是否是同一分区的
    if (sourceIndexPath.section == proposedDestinationIndexPath.section) {
        // 若是同一分区, 可以完成交换, cell的当前位置变为目的地位置
        return proposedDestinationIndexPath;
    } else {
        // 若是跨区操作, 不可以完成交换操作, 让cell的位置回到原地
        return sourceIndexPath;
    }
}

本方法主要是对cell的移动结果进行判断. 若合法, 则允许移动, 否则不允许移动(返回到原地).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值