2010-11-21 5 views
4

私はページングを有効にして、水平方向にスクロールするUIScrollviewを持っています。各ページはデータフィードを表します。各データフィードは、UITableViewに表示されるテキストや画像を含むかなりの量のメモリを消費します。ユーザーはデータフィードを無制限に持つことができるので、メモリ使用量を最大限に抑えるために遅延ロードする必要があります。私の考えは、任意のポイントで最大5つのデータフィードをメモリに保持し、その範囲外のものをリリースすることです。私の最初の取り組みは、ページをメモリ内のビューポートに保持し、2ページをその両端に保持することです。この方法で、ユーザーがスクロールすると、次のシーケンシャルページは常にメモリに保存され、すぐに表示されます。UIScrollViewツイストを使用したレイジーロードストラテジー

これは私の問題です:また、ユーザーが特定のデータフィードにスキップするシナリオをサポートする必要があります.10個以上のページが右または左に表示されます。

このシナリオをサポートするより良い戦略がありますか?

+0

Apple HIGは、一度に3つのビューをメモリに表示します。あなたは非常に速いスクロールジェスチャーに対応するために、それぞれの側面に別のものを追加しますか? – BoltClock

答えて

7

はい、できることは、テーブルビューに似た個々のセルを格納する外側のスクロールビューを作成することです。この点で、セルにはコンテンツビューがあり、データを配置することができます。そのようにする方法を知っていると仮定しましょう。

あなたがこのアーキテクチャーを思いついたら、それはかなり明確になります。セルの幅と画面のサイズを知ることができます。いくつかの簡単な数式で画面上の数を知ることができます。左または右に1つを追加できるので、ユーザーがスクロールするときにデータを事前にロードしています。

これは、スクロールビューのコンテンツビューの開始または終了時に3つが表示されている場合は最大5つのフィードを持ち、スクロールビューでは4つのフィードを持つことができます10億本のフィード。

これの重要な部分の1つは、セルの再利用です。あなたはリサイクルされたセルと目に見えるセルのためのカップルNSSetを維持します。リサイクルされたセルに画面外のアイテムを追加し、セルを設定するときにリサイクルされたセルからアイテムをデキューして、追加のメモリ割り当てを節約します。この戦略を使用しても、セルの再利用に関してはUITableViewと同じ警告に主観的です。

私はここで書いたソフトウェアを接続していますので、それを許してください。私がここで議論したことを実装していれば、私が話していることの一例として、そうしています。

最後のメモ。セルのスキップをサポートするには、スクロールビューのポイントを調整するだけの簡単な数学です。この動作はジェスチャーで行うことができますが、ここでは例としてアプリケーションに固有のいくつかの特定のプロパティを持つパンジェスチャ認識機能について説明します。また、本当に必要な場合は、ボタンを使用することもできます。セルへのオフセットを計算する方法を理解して、その点までスクロールしてください。あなたは大丈夫でしょう。

+0

NSSetsはなぜNSArraysよりも優れていますか? –

+0

この目的のために、NSSetのルックアップはO(1)オペレーションですが、NSArrayではO(n)です(nはコレクションの要素数)。私たちが一般的にやっていることであるNSSet上でルックアップが高速であることは驚くべきことではありません。 – jer

+0

3人すべてが素晴らしい答えでした。正直なところ、私はそれぞれのアイデアを使用することができました。 @jer、あなたのサンプルコードは実装のために正しい方向に私を指摘しました。ご協力いただきありがとうございます!!! –

1

質問に記載されている情報を正確に伝えるのは難しいです。だから私は質問を読むときに得たいくつかの考えを提示するだけです。

フィードをダウンロードするのに時間がかかりますか?最初のいくつかのアイテムがすぐに表示されるように、いくつかのアイテム(スクリーン・フル)をダウンロードすることは可能でしょうか?可能であれば、画像を怠けるかもしれません。

フィードデータをディスクにキャッシュすると考えましたか?そうすれば、すぐにデータを表示し、新しいデータがダウンロードされるたびにフィードを更新することができます。

各ページはフィードビューであるため、ユーザーはフィードを見ずにフィードをスクロールするだけですか?あなたは本当に両側に2つのビューをロードする必要がありますか、またはそれぞれの側にちょうど1つのビューで取り除くことができますか?

ユーザーが任意のページに直接スキップできるため、遅延読み込みスキームが機能しなくなるとは思わない。そのページが選択されたときにそのページのデータの読み込みを開始する必要がありますが、ディスクキャッシュを使用するか、または小さなサンプルをダウンロードするとアプリをより速く感じることができます。私はまた、選択されたページにアニメーションを付けるために何らかのアニメーションを使用すると、少し時間を買うことができると思います。ここで

1

私の問題である:我々はまた、窓の外に私の全体の遅延ロードスキームを投げ右または左への可能性が10ページ以上、ユーザーが特定のデータフィードにスキップすることができシナリオをサポートする必要があります。

次に、データ構造を修正する必要があります。私はこれをかなり正確に書いています(UITableViewのようなページングスクロールビュー)、うまくいきます(いくつかの再読み込みクォークがありますが、ちょっと...)。

  • ロードしたページを記録します。私は8を法とするリングバッファーを使用し、コードを正しく取得していました。おそらく、NSDictionaryをNSNumberキーとUIView値とともに使用するほうがずっと簡単です。これは、ページ1から10に変更したときに、ロードされたビューがページ1,2,3のためにあり、それらをドロップすることができます。
  • 必要なページを-layoutSubviewsに読み込みます。私は1または3をロードします。 5はおそらく多すぎます(ただし、ページ間にある場合は少なくとも2つは読み込む必要があります)。
  • -scrollViewDidScroll:に負荷3(片側に1つ)があります。これは、ページ1からページ2にスクロールしたときに、まだロードされていないページ4をロードしようとしないようにするためです。
  • willDecelerateがNOの場合、–scrollViewDidEndDragging:willDecelerate:に5をロードします(、–scrollViewDidScrollToTop:、および–scrollViewDidEndScrollingAnimation:)。アイデアはアニメーションが終了しているので、ユーザーが遅れを感じることなく余分なビューを読み込むことができます。あなたは1ページからにフリックするときので、私は「2つのページのいずれかの側」を行うことを決めた可能性
  • –scrollViewWillBeginDragging:で負荷5、ページ1

に現在している場合は、3ページがロードされていることを確認します2ページ目、それはバウンス時にページ3のピクセル幅のスライバーを表示することがよくあります。これはスクロールビューのインセットで回避できますが、その時点では考えていませんでした(oops)。そうでなければ3を超える5を選択する理由はそれほどありません。

これは正しいことですが、それ以外の場合は完璧に動作するようです。

関連する問題