Подтвердить что ты не робот

TableView reloadData vs. beginUpdates & endUpdates

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

Ситуация 1: Я использую [tbl reloadData];, где tbl мой TableView, для обновления TableView - работает по назначению.

Ситуация 2: Я использую:

[tbl beginUpdates];
[tbl reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationRight];
[tbl endUpdates];

Где tbl - мой TableView, а indexPaths - массив, содержащий все индексы, присутствующие в TableView. Теперь массив в порядке, он содержит все правильные indexPaths (двойные и тройные проверены), но по какой-то причине - это не работает должным образом.

Теперь я понимаю, что это проблема XY (где я прошу Y, но моя проблема действительно X, потому что я думаю, что решение Y будет решать X), и это только потому, что я чувствую, что это немного сложно объяснить X (следствие сказанного выше проблемы) простым способом, поэтому я бы скорее воздержался от этого, если это возможно.

Итак, вплоть до моего вопроса: Есть ли разница между двумя способами обновления TableView (за исключением фрагмента анимации, конечно) или я должен подозревать, что проблема лежит в другом месте?

EDIT: Хорошо, я попытаюсь объяснить, каковы симптомы:

В методе cellForRowAtIndexPath я добавляю кнопку для каждой ячейки с назначенным тегом, который равен строке indexPath ячейки, например:

btn.tag = indexPath.row;

Причина, по которой я это делаю, заключается в том, что я могу идентифицировать каждую кнопку, поскольку все они называют одну и ту же функцию:

- (void)btnPressed:(id)sender

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

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

4b9b3361

Ответ 1

Из документации UITableView

beginUpdates
Начните серию вызовов методов, которые вставляют, удаляют или выберите строки и секции ресивера.

Это означает, что вы не должны использовать это, если вы не вставляете, не удаляете и не выбираете. Вы ничего не делаете.

Кроме того, вы должны положить конец beginUpdates с помощью endUpdates, а не reloadData. Документация:

Эта группа методов должна завершиться вызовом endUpdates.

Ответ 2

Первое различие между reloadData и reloadRowsAtIndexPaths состоит в том, что при выполнении reloadRowsAtIndexPaths существует 2 UITableViewCell объектов, выделенных одновременно для одного и того же indexPath (потому что tableview "смешивается" в новой ячейке). Это иногда не предусмотрено кодом в cellForRowAtIndexPath. Сюрприз исходит из того факта, что даже если ячейка уже была выделена для определенного идентификатора ячейки, представление таблицы не возвращает вам эту ячейку в dequeueReusableCellWithIdentifier при вызове reloadRowsAtIndexPaths, вместо этого он возвращает nil. В противоречии reloadData повторно использует уже выделенные ячейки.

Второе различие заключается в том, что endUpdates после reloadRowsAtIndexPaths прямо вызывает cellForRowAtIndexPath (если вы установите там точку останова, в трассировке стека отображается endUpdates), тогда как reloadData назначает вызовы cellForRowAtIndexPath в позднее (не отображается в трассировке стека).

Однако вам нужно будет опубликовать немного больше кода, чтобы дать нам понять, что вы там делаете. В принципе, indexPaths новых ячеек идентичны старым и reloadRowsAtIndexPaths, если вы не удаляете или не вставляете строки.

Ответ 3

Вызов этого метода, если вы хотите, чтобы последующие операции вставки, удаления и выбора (например, cellForRowAtIndexPath: и indexPathsForVisibleRows) были анимированы одновременно.

Я думаю, что это то, что вы хотите. beginUpdates и endUpdates могут изменить UItableview с анимацией.