UITableVIew编辑分为两种状态
对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种
全局刷新数据方法, 也是最为常用的方法
- (void)reloadData;
用法为 [table reloadData];
reloadData可以刷新cell, Section headers和Section footers, indexPath数组等相关的数据
reloadData刷新不带动画, 触发及刷新整个界面的可视相关部分
删除数据响应刷新界面方法
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
第一个参数为被删除的数据所在的索引, 可以是一个数据, 也可以是多个数据. 第二个参数为删除数据时的动画效果
用法为:
// 之前必选先在数据源数据中将该数据删除
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:(UITableViewRowAnimationBottom)];
本方法可以用于删除多个indexPath对应的cell. 注意的是, 在调用本方法之前必须已经将该数据从数组中删除. 否则再对界面进行操作的时候会导致崩溃.
添加数据响应的刷新界面方法
- (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;
方法参照以上.
除了增删, 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是否相同进行判断是否是同分区操作
同区交换的时候, 需要对当前分区的数据源数组进行操作(通常用可变数组接受分区的元素).
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的移动结果进行判断. 若合法, 则允许移动, 否则不允许移动(返回到原地).