web-dev-qa-db-ja.com

UITableViewまたはUICollectionViewで読み込まれたセルと表示されたセルの取得

IOS 10の導入により、 ITableViewおよびUICollectionViewsでデフォルトでプリフェッチが有効になっている になるようです。これは、画面に表示されていないセルが、ユーザーに実際に表示される前にフェッチされることを意味します。

関連する方法は次のとおりです。

ITableView

  • cellForRowAtIndexPath: :「セルが表示されていない場合はnil」を返します。
  • visibleCells :各アイテムは「テーブルビューに表示されるセル」を表します。
  • indexPathsForVisibleRows :各アイテムは「テーブルビューに表示される行」を表します。

ICollectionView

  • visibleCells : "コレクションビューに表示される表示セルの完全なリストを返します。"
  • indexPathsForVisibleItems :各アイテムは「コレクションビューに表示されるセル」を表します。
  • cellForItemAtIndexPath: :「セルが表示されていない場合はnil」を返します。

これらはすべて、説明の中で「目に見える」と具体的に言及しています。 iOS 10でのプリフェッチの導入により、プリフェッチされたセルと現在表示されているセルをどのように区別できますか?

言い換えると:

  1. 表示されているすべてのセルを取得するにはどうすればよいですか?
  2. ロードされたすべてのセルを取得するにはどうすればよいですか?

UITableViewまたはUICollectionViewのいずれかにこれを支援できる新しいAPIがあるようには見えません。

20
Senseful

TL; DR

  • 関数名のvisibleを文字通り取ります。
  • UITableViewは、iOS9と同じように動作します。
  • IOS 10のUICollectionViewでロードされたセルと表示されたセルを異なる方法で処理する場合は、ブックキーピングを行う必要があります。

UITableViewとUICollectionViewは、プリフェッチに関しては非常に異なる動作をするように見えます。

最初に注意することは、プリフェッチセルとプリフェッチデータの間に違いがあることです。

  • セルのプリフェッチは、セルが実際に画面に表示される前に呼び出されるcellForRowAtIndexPathを指します。これにより、画面外にあるがまだロードされているセルがあるシナリオが可能になります。
  • データのプリフェッチは、画面に表示されるprefetchDataSourceについて通知するindexPathsメソッドを指します。このメソッドが呼び出されたときにセルへの参照がなく、このメソッドが呼び出されたときにセルを返しません。代わりに、このメソッドは、セルに表示される画像をダウンロードするためにネットワーク要求を起動するようなことを行う必要があります。

注:これらすべてのシナリオで、いつでも表示できるセルが8つあると想像してください。

UITableView:(オプション:no prefetching、またはprefetch data

  • セルをプリフェッチしません。つまり、表示されていないcellForRowAtIndexPathindexPathを呼び出すことはありません。
  • そのため、UITableViewにはisPrefetchingEnabledプロパティはありません。
  • prefetchDataSourceを使用して、データのプリフェッチにオプトインできます。
  • テーブルビューは セルの再利用ではそれほど積極的ではない のように見えますが、再利用されたセルが画面に戻ったときにcellForItemAtIndexPathを呼び出すように見えることに注意してください。 (ただし、特にコレクションビューの場合は、これについてさらに調査する必要があるかもしれません。)

UICollectionView:(オプション:no prefetchingprefetch cells、またはprefetch cells and data

  • デフォルトでは、セルをプリフェッチします。つまり、すぐに表示されないセルに対してはcellForItemAtIndexPathを呼び出します。
  • セルのプリフェッチは、ユーザーがコレクションビューを上下にスクロールしたときにのみ開始されます。つまり、ビューが読み込まれると、cellForItemAtIndexPathが正確に8回呼び出されます。ユーザーが下にスクロールすると、非表示のセルを要求し始めます(たとえば、下にスクロールして2-10を表示すると、11-14を要求する場合があります)。
  • プリフェッチされた非表示のセルが画面に表示されると、cellForItemAtIndexPathを再度呼び出すことはありません。最初に行ったインスタンス化はまだ有効であると想定します。
  • prefetchDataSourceを使用して、データのプリフェッチにオプトインできます。
  • prefetchDataSourceは、初期ロードにのみ役立つことがわかりました。上記の同じシナリオでは、最初の8つのセルが表示されると、たとえば、セル9〜14のデータのプリフェッチが開始される場合があります。ただし、この最初のメソッドが呼び出されると、それ以降は役に立ちません。これは、cellForItemAtIndexPathが呼び出されるたびにprefetchItemsAtが呼び出されるためです。たとえば、prefetchItemsAt:[14, 15]の直後にcellForItemAt:14cellForItemAt:15が続きます。
  • isPrefetchingEnabled = falseを設定することにより、allプリフェッチ動作をオプトアウトできます。これは、UICollectionViewをprefetchDataSourceを使用したUITableViewと同様に動作させることができないことを意味します。または、言い換えると、UICollectionView prefetch dataのみを持つことはできません。

両方の場合

  • visibleCellsindexPathsForVisibleRows、およびcellForItemAtIndexPathは、彼らが言うとおりに機能します。つまり、visibleセルのみを処理します。同じシナリオで、20個のセルがロードされているが、画面に表示されるのは8個だけである場合。これらの3つの方法はすべて、画面上の8つのセルについてのみ報告します。

では、これはどういう意味ですか?

  • UITableViewを使用している場合は、そのまま使用でき、読み込まれたセルと表示されているセルの違いについて心配する必要はありません。それらは常に同等です。
  • 一方、UICollectionViewの場合、この違いを気にする場合は、ロードされた非表示セルと表示セルを追跡するために、簿記を行う必要があります。これを行うには、データソースのいくつかのメソッドとデリゲートメソッド(willDisplayCell、didEndDisplayingCellなど)を確認します。
27
Senseful