Короткий ответ: вам нужно буферизовать данные в вашей модели данных и обновлять таблицу только новыми данными, когда таблица не прокручивается.Это необходимо сделать в модели данных, поскольку делегат источника данных не имеет представления о том, что находится внутри модели данных или что изменилось.
Однако, с точки зрения дизайна пользовательского интерфейса, активное обновление таблицы во время прокрутки пользователя дезориентирует пользователя.Пользователь будет думать, что он находится в верхней / средней / нижней части таблицы, а затем вдруг окажется в нижней / верхней / средней части.Пользователь будет думать, что он просмотрел все данные в одном разделе таблицы, но в действительности в таблицу будет добавлено то, что ему нужно было увидеть.Например, если таблица представляет собой список имен в алфавитном порядке, пользователь проверяет все имена, начинающиеся с «U», видит, что их нет, и затем проверяет где-нибудь еще в таблице.Между тем, таблица незаметно обновляет раздел «U» свежими именами, пока пользователь ищет в другом месте.Даже если пользователь понимает, что таблица динамически обновляется (а большинство нет), ему придется постоянно прокручивать, проверяя практически всю таблицу, чтобы увидеть, что изменилось.
Лучший дизайн пользовательского интерфейса - дать пользователю возможность обновляться.Поместите кнопку «Обновить» или «Доступны новые данные» на панели, а затем установите, чтобы она появлялась при поступлении новых данных.После нажатия на кнопку заморозить таблицу, обновить и только после этого позволить пользователю возобновить взаимодействие.Также было бы неплохо визуально пометить добавленные строки.
Это сделает пользовательский интерфейс более понятным для пользователя и одновременно решит проблему сбоев.
Edit01:
Если вы не используете Core Data, чтобы реализовать живое и невидимое обновление таблицы.Вам нужно будет зафиксировать вызовы – tableView:numberOfRowsInSection
или – numberOfSectionsInTableView:
до вызова – tableView:cellForRowAtIndexPath:
.
Поскольку сначала вызывается – tableView:numberOfRowsInSection
, я бы позвонил туда, чтобы сначала обновить, а затем заморозить вашу модель данных.Таким образом, модель данных будет возвращать правильное количество разделов и строк.
Полагаю, вам придется разделить модель данных на две секции, одна из которых будет буферизовать входящие данные, а другая - упорядочивать данные для отображения.Ваш метод обновления должен переместить все окончательные буферизованные данные в раздел отображаемых данных.
Кроме того, вам, вероятно, потребуется установить таймер, когда пользователь не перемещает стол.Таймер должен вызывать метод обновления, если с таблицей не ведутся активные манипуляции, а затем он должен инициировать обновление.
Если вы используете Core Data, вы можете использовать NSFetchedResultController
, и его методы делегата сообщат вам, когда изменится модель данных.Он должен возвращать правильный раздел и информацию о строке, обновленную в прямом эфире.Управлять таблицей обновлений довольно просто.Однако это не решит проблему ввода данных в модель так быстро, что модель меняется между вызовами методов.Вам все равно придется заморозить и / или замедлить модель.Однако вам не понадобится таймер.
Базовые данные - ваш лучший вариант, но даже в этом случае их будет сложно реализовать, потому что вы пытаетесь что-то сделать против структуры пользовательского интерфейса и, следовательно, API не так легко его поддерживает.
Обновление:
Оглядываясь назад, я вижу, что не упомянул [UITableView beginUpdates]
, который замораживает конфигурацию таблицы при добавлении или удалении строк.Он связан с [UITableView endUpdates]
для включения изменений в пользовательский интерфейс.