Удаление UITableViewCell из UITableView

Я использую fmdb для управления некоторыми данными, которые отображаются в обычном UITableView. Я пытаюсь удалить одну ячейку с помощью этого кода:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];


        [db open];

        [db beginTransaction];

        NSString * stringtoInsert = [NSString stringWithFormat: @"DELETE FROM TTLogObject WHERE id='%@'", [idArray objectAtIndex:indexPath.row]];

        BOOL success = [db executeUpdate:stringtoInsert];

        if (!success)
        {
            NSLog(@"insert failed!!");
        }

        NSLog(@"Error %d: %@", [db lastErrorCode], [db lastErrorMessage]);

        [db commit];

        [db close];

        [self getList];
    }
}

Вот код для viewDidLoad и функции getList, которую я использую.

   - (void)viewDidLoad
{
    [super viewDidLoad];

     self.navigationController.navigationBar.tintColor = [UIColor blackColor];

    shipperCityArray = [[NSMutableArray alloc] init];
    pickupDateArray = [[NSMutableArray alloc] init];
    paidArray = [[NSMutableArray alloc] init];
    idArray = [[NSMutableArray alloc] init];

    //NSString *path  = [[NSBundle mainBundle] pathForResource:@"tt" ofType:@"db"];


    [self getList];

}

- (void)getList
{
    db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];
    [shipperCityArray removeAllObjects];
    [pickupDateArray removeAllObjects];
    [paidArray removeAllObjects];
    [idArray removeAllObjects];

    [db open];

    FMResultSet *fResult= [db executeQuery:@"SELECT * FROM TTLogObject"];


    while([fResult next])
    {
        [shipperCityArray addObject:[fResult stringForColumn:@"shipperCity"]];
        [pickupDateArray addObject:[fResult stringForColumn:@"pickupDate"]];
        [paidArray addObject:[NSNumber numberWithBool:[fResult boolForColumn:@"paid"]]];
        [idArray addObject:[NSNumber numberWithInteger:[fResult intForColumn:@"id"]]];
        NSLog(@"%@", [NSNumber numberWithInteger:[fResult intForColumn:@"id"]]);
    }


    [db close];

    [self.tableView reloadData];
}

Проблема в том, что данные просто удаляются из базы данных. Однако после нажатия кнопки удаления в табличном представлении больше не отображаются ячейки. Когда я перезапускаю приложение, правильные данные загружаются снова, а удаленная ячейка фактически исчезает. Я подозреваю, что это как-то связано с numberOfRowsInSection.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSLog(@"%i", [shipperCityArray count]);
    return [shipperCityArray count];
}

Когда приложение запускается, оно печатает нужное количество ячеек, но когда удаляется удаление, оно ничего не печатает и, кажется, не вызывается.

Я попытался использовать [self.tableView beginUpdates] и [self.tableView endUpdates], но они, похоже, ошибаются, говоря что-то о неправильном количестве элементов, полученных после удаления. Я не знаю, как это решить. Если мне нужно использовать beginUpdates и endUpdates, может ли кто-нибудь объяснить мне, как это должно быть сделано правильно и что на самом деле происходит?


person Paulius Dragunas    schedule 20.08.2013    source источник


Ответы (1)


Вместо вызова reloadData вам нужно явно указать tableView, что вы удаляете ячейку. Заменять

[self.tableView reloadData];

с участием

[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];

Вы должны вызвать это в своем методе commitEditingStyle.

person Erik Godard    schedule 20.08.2013
comment
Я пытаюсь использовать это, что мне передать в deleteRowsAtIndexPaths? Прямо сейчас, если я просто оставлю строку кода как есть, я получу следующую ошибку: - [NSIndexPath count]: неопознанный селектор отправлен в экземпляр 0x7566e50 2013-08-19 22: 57: 28.808 Trucking Tracker [13861: c07] *** Завершение работы приложения из-за неперехваченного исключения «NSInvalidArgumentException», причина: «- [NSIndexPath count]: нераспознанный селектор отправлен в экземпляр 0x7566e50» - person Paulius Dragunas; 20.08.2013
comment
Он ожидает массив путей индекса, а не один, поэтому вы должны предоставить ему массив из одного элемента. Я только что обновил его, извините за это. - person Erik Godard; 20.08.2013
comment
Ах, я пробовал это. И если я сделаю это, как показано, это даст мне следующее: *** Завершение работы приложения из-за неперехваченного исключения 'NSInternalInconsistencyException', причина: 'Недействительное обновление: недопустимое количество строк в разделе 0. Количество строк, содержащихся в существующем разделе после обновление (2) должно быть равно количеству строк, содержащихся в этом разделе перед обновлением (2), плюс или минус количество строк, вставленных или удаленных из этого раздела (0 вставлено, 1 удалено) и плюс или минус число строк, перемещенных в этот раздел или из него (0 перемещено, 0 перемещено). ' - person Paulius Dragunas; 20.08.2013
comment
Вам нужно вызвать его после вызова метода getList, чтобы метод count возвращал правильное количество элементов. - person Erik Godard; 20.08.2013
comment
Хм, мне просто не повезло с этим, теперь это дает мне следующее: *** Ошибка утверждения в - [UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableView.m:862 19.08.2013 23 : 06: 22.926 Отслеживание грузовиков [14743: c07] *** Завершение работы приложения из-за неперехваченного исключения «NSInternalInconsistencyException», причина: «попытка удалить строку 3 из раздела 0, который содержит только 3 строки до обновления» - person Paulius Dragunas; 20.08.2013
comment
Понятно, reloadData все еще вызывается в getList, и его просто нужно удалить. Спасибо - person Paulius Dragunas; 20.08.2013