iOS UITableView 避免删除数据越界崩溃。

2019-04-28  本文已影响0人  CarrySniper

UITableView删除数据容易崩溃,大部分原因是由于indexPath的值大于数据源数组大小导致的。这里分Row、和Section写法,功能一样的。

删除功能要求删除下面三项,才算成功。

一、声明属性,调用方法,方便看代码
/** 数据源 */
@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];
}
- (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];
}
上一篇 下一篇

猜你喜欢

热点阅读