UITableView reloadRowsAtIndexPaths: кажется, нарушает insertRowsAtIndexPaths: - PullRequest
3 голосов
/ 01 апреля 2012

У меня есть UITableView, в который пользователь может вставлять новые строки.Когда это происходит, я хочу перезагрузить все старые строки в таблице.Одним из решений было бы просто вызвать reloadData, как только вставка произойдет, что полностью работает, но это означает, что я не получаю анимацию вставки.

Поэтому, когда пользователь нажимает «добавить строку»кнопку, я вызываю reloadRowsAtIndexPaths: с каждым путем индекса, кроме только что вставленного.Затем я вызываю insertRowsAtIndexPaths: только с новой вставленной строкой.Разумно, верно?

Это приводит к сбою приложения со следующим объяснением:

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

Это происходит, как вы можете видеть в этом примере, даже когда reloadRowsAtIndexPaths передается пустой массивиндексных путей.

Ах!Мне нужно обернуть два вызова с beginUpdates и endUpdates.Справедливо.Но теперь анимация полностью нарушена.

Я выполняю перезагрузку с UITableViewRowAnimationFade и вставку с UITableViewRowAnimationAutomatic.Но во время анимации высота каждой строки изменяется, создавая этот странный мерцающий эффект, который выглядит просто ужасно.Как правильно анимировать эти изменения?

Редактировать:

Из документов для reloadRowsAtIndexPaths:withRowAnimation::

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

Я думаю, что в моем приложении ручное обновление каждой ячейки - правильный путь.Тем не менее, я все еще обеспокоен этой странной ошибкой анимации и хотел бы знать, какова ее причина / что бы я сделал, если бы действительно «хотел предупредить пользователя об изменении значения ячейки».

Ответы [ 2 ]

4 голосов
/ 11 мая 2012

Распространенной причиной получения этой ошибки, как утверждают документы, является источник данных, запрашивающий ячейку.Может быть менее понятно, что его просят дважды ... один раз, чтобы предоставить начальные данные, еще раз, чтобы предоставить окончательные данные.Это означает, что tableView: numberOfRowsInSection: метод должен возвращать старые значения до beginUpdates и новые значения после endUpdates (или, если вы используете метод ярлыка, до и после вызова).Не забывайте и о numberOfSectionsInTableView, если он уместен.

Пример:

    numberOfRows... return [array count];

    // Incorrect
    [array addObject:object];
    [tableView beginUpdates];
    [tableView insertRow..];
    [tableView endUpdates];

    // Correct
    [tableView beginUpdates];
    [array addObject:object];
    [tableView insertRow..];
    [tableView endUpdates];

В вашем конкретном случае я бы рекомендовал выполнить вставку, а затем вызывать reloadData для всего табличного представления так долгопоскольку это не портит вашу анимацию или что-то еще.

0 голосов
/ 01 апреля 2012

Вам не нужно выполнять никаких операций с точными ячейками.Все, что вам нужно - это изменить массив источника данных, затем вызвать reload data / row / section, и вы получите измененные данные в виде таблицы с добавленными строками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...