Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: Ethan AllenОтветов: 2

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

- (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
  • Обычно вы используете первый метод в современных настройках tableView. Второй метод - довольно старый процедурный способ, который позволит вам делать несколько вещей одновременно. Ryan Poolos 07.06.2013
  • [namesArray removeObjectAtIndex:indexPath.row];[tableView reloadData]; El Tomato 07.06.2013

ioscocoa-touchobjective-cuitableview

Ответы

Ответ 1 · рейтинг 3 · Community

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

Ответ 2 · рейтинг 3 · sangony

После того, как таблица перейдет в режим редактирования, табличное представление спросит у источника данных, должна ли каждая строка быть редактируемой. Если реализован метод 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 и более поздних версиях).

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы