2016-08-25 4 views
16

С введением iOS 10 кажется, что у нас будет prefetching enabled by default on UITableView and UICollectionViews. Это означает, что ячейки, которые не отображаются на экране, будут извлекаться до того, как пользователь их действительно увидит.Получение загруженных vs видимых ячеек в UITableView или UICollectionView

Вот некоторые важные методы:

UITableView:

  • cellForRowAtIndexPath:: возвращает "nil, если клетка не видно."
  • visibleCells: каждый элемент представляет собой «видимую ячейку в виде таблицы».
  • indexPathsForVisibleRows: каждый элемент представляет «видимую строку в виде таблицы».

UICollectionView:

  • visibleCells: "возвращает полный список видимых ячеек, отображаемых в целях сбора."
  • indexPathsForVisibleItems: каждый элемент представляет собой «видимую ячейку в виде коллекции».
  • cellForItemAtIndexPath:: возвращает «nil, если ячейка не отображается».

Все это специально упоминает «видимые» в своих описаниях. С введением предварительной выборки в iOS 10, как бы я мог различать предварительно выбранную ячейку против той, которая в настоящее время видима?

Другими словами:

  1. Как получить все видимые ячейки?
  2. Как получить все загруженные ячейки?

Не похоже, что в UITableView или UICollectionView есть какие-либо новые API-интерфейсы, которые могут помочь в этом.

+0

Там новый протокол '' UITableViewDataSourcePrefetching' для UITableView' в прошивке 10. Я написал статью об этом и сделал несколько измерений: https://andreygordeev.com/2017/02/20/uitableview-prefetching/ –

ответ

22

TL; DR

  • Возьмите visible в именах функций буквально.
  • UITableView ведет себя так же, как это было в прошивке 9.
  • Вам нужно сделать некоторую бухгалтерию, если вы хотите, чтобы лечить загружены против видимых ячеек по-разному в UICollectionView на прошивке 10.

UITableView и UICollectionView, похоже, ведут себя по-разному, когда дело доходит до предварительной выборки.

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

  • упреждающей выборкой клетки относится к cellForRowAtIndexPath Называнию до ячейки фактически отображаются на экране. Это позволяет использовать сценарий, в котором у вас есть ячейки, которые находятся вне экрана, но все еще загружены.
  • Предварительная выборка данных относится к методам prefetchDataSource, которые сообщают вам о indexPaths, которые будут отображаться на экране. У вас нет ссылки на ячейку при вызове этого метода, и вы не возвращаете ячейку при вызове этого метода. Вместо этого этот метод должен делать такие вещи, как отключение сетевого запроса, чтобы загрузить изображение, которое будет отображаться в ячейке.

Примечание: во всех этих сценариях представьте, что в любой момент времени могут отображаться 8 ячеек.

UITableView: (варианты: no prefetching или prefetch data)

  • Не упреждающий клетки, когда-либо. Другими словами, он никогда не вызовет cellForRowAtIndexPath на indexPath, который не отображается.
  • Таким образом, в UITableView отсутствует свойство isPrefetchingEnabled.
  • Вы можете сделать выборку для предварительной выборки данных с помощью prefetchDataSource.
  • Обратите внимание, что хотя вид таблицы выглядит как less aggressive with reusing cells, он по-прежнему вызывает вызов cellForItemAtIndexPath, когда повторно используемая ячейка возвращается на экран. (Хотя я, возможно, придется сделать некоторые исследования, чтобы это, особенно для видов сбора.)

UICollectionView: (варианты: no prefetching, prefetch cells или prefetch cells and data)

  • предварительную выборку клетки по умолчанию. Другими словами, он вызовет cellForItemAtIndexPath для ячеек, которые не будут немедленно отображаться.
  • Предварительная выборка ячеек начинается только тогда, когда пользователь выполняет прокрутку вверх или вниз по представлению коллекции. Другими словами, вы получите ровно 8 вызовов до cellForItemAtIndexPath при загрузке представления. Только после того, как пользователь прокрутится вниз, он начнет запрашивать невидимые ячейки (например, если вы прокрутите вниз, чтобы показать 2-10, он может запросить 11-14).
  • Когда на экране появляется запрограммированная, невидимая ячейка, она не будет звонить снова cellForItemAtIndexPath. Он предположит, что экземпляр, который вы делали в первый раз, по-прежнему действителен.
  • Вы можете сделать выборку для предварительной выборки данных с помощью prefetchDataSource.
  • prefetchDataSource оказывается полезным только при начальной нагрузке.В том же сценарии выше, когда отображаются первые 8 ячеек, он может, например, сбрасывать предварительную выборку данных для ячеек 9-14. Однако, как только этот первоначальный метод вызывается, это бесполезно после этого. Это связано с тем, что cellForItemAtIndexPath вызывается сразу после каждого звонка до prefetchItemsAt. Например, вы получите prefetchItemsAt:[14, 15], а затем cellForItemAt:14, cellForItemAt:15.
  • Вы можете отказаться от всего поведения предварительного запроса, установив isPrefetchingEnabled = false. Это означает, что вы не можете заставить UICollectionView вести себя аналогично UITableView с prefetchDataSource. Или, другими словами, вы не можете использовать UICollectionView prefetch data.

Для обоих:

  • visibleCells, indexPathsForVisibleRows и cellForItemAtIndexPath делать именно так, как они говорят: они занимаются только с видимых клеток. В том же сценарии, если у нас есть 20 ячеек, но на экране видны только 8. Все три из этих методов будут сообщать только о 8 экранных ячейках.

Так что это значит?

  • Если вы используете UITableView, вы можете использовать его как есть и не должны беспокоиться о различии между загружаемыми и видимыми ячейками. Они всегда эквивалентны.
  • Для UICollectionView, с другой стороны, вам нужно будет сделать некоторые бухгалтерские книги, чтобы отслеживать загруженные, невидимые ячейки или видимые ячейки, если вы беспокоитесь об этой разнице. Вы можете сделать это, просмотрев некоторые из методов в источнике данных и делегировать методы (например, willDisplayCell, didEndDisplayingCell).
+0

«Если вы используете UITableView, вы можете использовать его как есть и никогда не должны беспокоиться о различии между загружаемыми и видимыми ячейками. Они всегда эквивалентны». Это верно для _cells_. Проблема заключается в _data_. Когда сначала открывается представление таблицы, 'prefetchRowsAt' _not called_ для первоначально видимых строк. Итак, как вы должны получать данные для этих строк без дублирования всего кода? Я считаю это серьезной ошибкой. Я вижу, как обойти это, но мне не нужно. Эти строки должны быть в первую очередь в списке_ для предварительной выборки, а это не так. – matt