2013-10-02 4 views
3

У меня было приложение, которое работает в iOS6, но когда я обновил iOS7 с тем же кодом, с которым я работал, я получаю эту ошибку, когда пытаюсь удалить строку в таблица:Ошибка при удалении строки в UITableView (только в iOS7)

2013-10-02 17:44:11.344 Goal[1877:a0b] *** Assertion failure in -[UITableView 
    _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2903.2/UITableView.m:1330 
2013-10-02 17:44:11.384 Goal[1877:a0b] *** Terminating app due to uncaught exception  'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows 
in section 0. The number of rows contained in an existing section after the 
update (1) must be equal to the number of rows contained in that section 
before the update (1), plus or minus the number of rows inserted or 
deleted from that section (0 inserted, 1 deleted) and plus or 
    minus the  number of rows moved into or out of that section 
(0 moved in, 0 moved out).' 

вот некоторые методы, если вам это нужно

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete the row from the data source 
     // deleting 
     NSManagedObjectContext *moc = self.managedObjectContext; 
     Goal *goalToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
     [moc deleteObject:goalToDelete]; 
     [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
    } 

} 

еще один

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"GoalCell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 

// Configure the cell... 
cell.textLabel.backgroundColor = [UIColor clearColor]; 

Goal *goal = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
cell.textLabel.text = goal.title; 

return cell; 
} 

и нет, я не Бесполезный забудьте проверить свой идентификатор соты,

ответ

1

Сообщение об ошибке довольно ясно:

  • Количество строк перед обновлением = 1
  • Количество строк = 1
  • Количество строк после обновления = 1 (это должно быть 0)

Ошибка в методе numberOfRowsAtIndexPath. Он должен возвращать 1 меньше количества строк перед удалением. Возвращаемое значение этого метода должно соответствовать количеству строк, которые вы ожидаете иметь в вашем UITableView.

Кроме того, ваш код будет врезаться в любой версии IOS, а не только 7.

1

Перед вызовом [Tableview deleteRowsAtIndexPaths: @ [indexPath] withRowAnimation: UITableViewRowAnimationFade]; Уменьшение «numberOfRows», которое возвращает номер функции OfRowsInSection.

+0

Если у вас есть более продвинутая реализация UITableViewSource, где у вас есть переменная, свойство или метод, отслеживающий количество строк (в разделе при использовании разделов), Мехмет прав, что вам нужно будет убедиться, что количество строк уменьшается. Перед вызовом deleteRowsAtIndexPath количество строк должно быть уменьшено на количество удаленных строк. Спасибо, Мехмет! – Miros

2

Я думаю, вы получаете сообщение об ошибке, потому что вы звоните deleteRowsAtIndexPaths дважды: один раз в commitEditingStyle и в другое время в ваших методах NSFetchedResultsControllerDelegate после обновления вашего MOC.

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

Когда строка удаляется действием пользователя, в представлении таблицы сообщается : через метод делегата commitEditingStyle. Затем ваша задача обновить вашу модель данных, чтобы она соответствовала тому, что уже известно в виде таблицы. Вам не нужно сообщать таблицу.

Только при программном изменении модели данных, которую необходимо сообщить в виде таблицы, вызывая методы вставки/удаления/перемещения.

+1

Ваш комментарий о вызове 'deleteRowsAtIndexPath' в' commitEditingStyle' неверен. [Из документации] (https://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewDataSource_Protocol/Reference/Reference.HTML # // apple_ref/ОКК/intfm/UITableViewDataSource/Tableview: commitEditingStyle: forRowAtIndexPath :): «** источник данных ** совершает вставку или удаление путем вызова методов UITableView insertRowsAtIndexPaths: withRowAnimation: или deleteRowsAtIndexPaths: withRowAnimation: , в зависимости от ситуации ". –

+1

@Rizwan Вы абсолютно правы. Спасибо что подметил это. Я вернулся и посмотрел на свой собственный код, и на самом деле 'deleteRowsAtIndexPaths' вызывался косвенно другим методом. Мне кажется странным, что 'commitEditingStyle' и' moveRowAtIndexPath' работают по-разному. –

Смежные вопросы