UITableView删除数据容易崩溃,大部分原因是由于indexPath的值大于数据源数组大小导致的。这里分Row、和Section写法,功能一样的。
删除功能要求删除下面三项,才算成功。
- 1.删除网络数据
- 2.删除数据源数据
- 3.删除UITableViewCell数据
一、声明属性,调用方法,方便看代码
/** 数据源 */
@property (nonatomic, strong) UITableView *tableView;
/** 数据源 */
@property (nonatomic, strong) NSMutableArray *dataArray;
// 1.删除行Row
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
// 2.删除组Section
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
二、系统自带左滑删除方法
说明:这样获取的indexPath是完全正确的,这里删除同步删除了数据源数据和UITableViewCell数据,达到需求,不会崩溃。
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
// 删除数据源
[self.dataArray removeObjectAtIndex:indexPath.row];
// 删除Cell
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}];
return @[deleteAction];
}
三、自定义UITableViewCell,添加删除按钮、点击事件如:
说明:根据按钮Tag或者Cell传递的indexPath可能错误的,这样的indexPath会保留原值,会和数据源数据大小不一致造成越界和删错数据。这个时候需要用从数据源获取对应的indexPath才是正确的。
- 正确的做法
- (void)deleteClickAction:(UIButton *)sender {
id xxx = 这个按钮所在Cell的数据对象,在tableView: cellForRowAtIndexPath:里面赋值的
// 获取NSIndexPath
NSUInteger row = [self.dataArray indexOfObject:xxx];
NSUInteger section = 1;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
// 删除数据源
[self.dataArray removeObjectAtIndex:indexPath.row];
// 删除Cell
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
- 错误的做法。tag的值不等于indexPath的值,当值大于时就会越界崩溃。
- (void)deleteClickAction:(UIButton *)sender {
// 获取NSIndexPath
NSUInteger row = sender.tag;
NSUInteger section = 1;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
// 删除数据源
[self.dataArray removeObjectAtIndex:indexPath.row];
// 删除Cell
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
网友评论