Как правильно удалить строку из UITableView?

У меня есть следующие примеры кода:

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

    if (editingStyle == UITableViewCellEditingStyleDelete) 
    {
        [namesArray removeObjectAtIndex:indexPath.row];

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];        
    }   
}

и

if ([nameSection count] == 0)
{
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
      [tableView beginUpdates];
      [indexKeys removeObjectAtIndex:section];
      [tableView deleteSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
      [tableView endUpdates];
}

Обратите внимание на порядок.... в первом примере я сначала удаляю объект из своего массива, а затем удаляю строку из таблицы.

Во втором примере я удаляю строку из таблицы, затем раздел из моего массива, затем раздел из таблицы.

Это правильный порядок действий? Или я должен сначала удалить его из пользовательского интерфейса, а затем массивы?

Причина, по которой я спрашиваю, заключается в том, что некоторые пользователи сообщают об этих сбоях, которые я не могу воспроизвести:

NSInternalInconsistencyException — недопустимое обновление: недопустимое количество строк в разделе 1. Количество строк, содержащихся в существующем разделе после обновления (0), должно быть равно количеству строк, содержащихся в этом разделе до

с этой трассировкой стека:

1: libobjc.A.dylib  objc_exception_throw 32
2: CoreFoundation  [NSException raise:format:] 0
3: Foundation  -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] 90
4: UIKit  -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] 6042
5: UIKit  -[UITableView _updateRowsAtIndexPaths:updateAction:withRowAnimation:] 254
6: UIKit  -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] 26
7: Movies  _mh_execute_header 253319
8: UIKit -[UITableView(UITableViewInternal) animateDeletionOfRowWithCell:] 84
9: CoreFoundation  -[NSObject performSelector:withObject:withObject:] 52
10: UIKit  -[UIApplication sendAction:to:from:forEvent:] 62

person Ethan Allen    schedule 07.06.2013    source источник
comment
Обычно вы используете первый метод в современных настройках tableView. Второй метод — довольно старый процедурный способ, который позволит вам делать несколько вещей одновременно.   -  person Ryan Poolos    schedule 07.06.2013
comment
[namesArray removeObjectAtIndex:indexPath.row];[tableView reloadData];   -  person El Tomato    schedule 07.06.2013


Ответы (2)


Вы должны обновить свою модель данных сначала, иначе табличное представление будет путаться в правильном количестве строк и разделов.

person Community    schedule 07.06.2013

После того, как таблица перейдет в режим редактирования, табличное представление спросит у источника данных, должна ли каждая строка быть редактируемой. Если реализован метод tableView:canEditRowAtIndexPath:, он вызывается для каждой строки по очереди.

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        return NO;
    }
    return YES;
}

Установив, можно ли редактировать строку, табличное представление затем спрашивает делегата, какой стиль редактирования следует использовать для каждой строки:

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewCellEditingStyleDelete;
}

При нажатии кнопки «Удалить» tableView отправляет сообщение tableView:commitEditingStyle:forRowAtIndexPath: источнику данных. Он принимает три параметра:

1) Ссылка на сам tableView (на случай, если источнику данных нужно различать несколько tableView).

2) UITableViewCellEditingStyle только что нажатого элемента управления — в данном случае UITableViewCellEditingStyleDelete

3) Объект indexPath, определяющий местонахождение рассматриваемой строки.

Когда источник данных получает сообщение commitEditingStyle:forRowAtIndexPath:, ему необходимо сделать две вещи:

1) Обновите модель tableView, удалив объект, представленный строкой в ​​таблице. Помните, что сама таблица — это просто представление, и если мы не удалим объект из модели, он снова появится в таблице при следующей перезагрузке таблицы.

2) Отправьте сообщение tableView:deleteRowsAtIndexPath:withRowAnimation: в tableView, чтобы оно обновило отображение таблицы. В этом случае, поскольку мы имеем дело с Delete, он будет анимировать удаленную ячейку, скользящую влево, а затем перемещать ячейки под ней вверх, чтобы закрыть зазор.

-(void)tableView:(UITableView *)tableView 
  commitEditingStyle:(UITableViewCellEditingStyle)editingStyle 
   forRowAtIndexPath:(NSIndexPath *)indexPath {
        if (editingStyle == UITableViewCellEditingStyleDelete) {
            [self.tableData removeObjectAtIndex:indexPath.row];
            NSArray *indexPathArray = [NSArray arrayWithObject:indexPath];
            [tableView deleteRowsAtIndexPaths:indexPathArray
                             withRowAnimation:UITableViewRowAnimationAutomatic];
        }
    }

На выбор предлагается ряд анимаций вставки и удаления ячеек таблицы:

  1. UITableViewRowAnimationFade — появление и исчезновение строк.
  2. UITableViewRowAnimationRight — вставленные строки скользят справа; удаленные строки выдвигаются вправо.
  3. UITableViewRowAnimationLeft — вставленные строки скользят слева; удаленные строки выдвигаются влево.
  4. UITableViewRowAnimationTop — вставленные строки скользят вниз от нижней части строки выше; удаленные строки перемещаются вверх к нижней части строки выше.
  5. UITableViewRowAnimationBottom — вставленные строки скользят вверх от верхней части ячейки ниже; удаленные строки кажутся покрытыми строкой ниже, скользящей вверх.
  6. UITableViewRowAnimationNone — просто появляются вставленные строки; удаленные строки просто исчезают.
  7. UITableViewRowAnimationMiddle — ячейки вставляются и удаляются с эффектом аккордеона.
  8. UITableViewRowAnimationAutomatic — tableView автоматически выбирает подходящий стиль анимации (доступен только в iOS 5 и более поздних версиях).

Отличная книга о том, как работать с таблицами, находится здесь.

person sangony    schedule 07.06.2013