iPhone UITableViewのスクロールパフォーマンスを向上させるためのコツ?


89

各セルにかなり大きな画像を読み込むuitableviewがあり、セルの高さは画像のサイズによって異なります。スクロールのパフォーマンスはまともですが、ぎくしゃくすることもあります。

私はFieryRobotブログでこれらのヒントを見つけました。

uitableview付きのガラス状スクロール

よりグラスっぽいスクロール-with-uitableview

uitableviewのスクロールパフォーマンスを向上させるためのヒントはありますか?


セルの高さをキャッシュする必要がある場合(計算にコストがかかり、頻繁に使用されることもあります)、例を示しました。これがアプリケーションに適している場合にのみ使用してください。 stackoverflow.com/questions/1371223/...
ポール・ド・ランゲ

回答:


156
  1. 行の高さをキャッシュします(テーブルビューはこれを頻繁に要求できます)
  2. テーブルで使用されているイメージの最も最近使用されていないキャッシュを作成します(メモリ警告を受け取ったら、すべての非アクティブなエントリを無効にします)。
  3. 可能な限りサブビューを避けて(または、標準のユーザー補助機能が必要な場合はコンテンツビューの)、UITableViewCellのすべてを描画します。drawRect:drawRect:
  4. あなたの作るUITableViewCellの層の不透明(お持ちの場合は、同じコンテンツビューのために行きます)
  5. UITableView例/ドキュメントで推奨されているreusableCellIdentifier機能を使用する
  6. 避け勾配/複雑なグラフィック効果にプリベークされていませんUIImage

5
さらに、ダウンロードした画像は、セルに表示する前にimageViewのサイズに縮小する必要があります。
ゾルタンMatók

4
この回答に、ここ数年の私の経験を付け加えたいと思います。透明なセルがあることは、おそらくスクロールのパフォーマンスの低下の原因にはなりません。非常に複雑なセル(20以上のサブビュー)を備えたアプリがあり、背景を表示するのはすべて透明です。適切な最適化により、透明度は3GSでも違いはありません。実際、最も遅くなったのは、テーブルビューからデキューするのに十分なセルがなくなる前にnibのロードでした。サブビューを使用する場合は、効率的な階層があることを確認してください。drawRectを使用する必要はありません。
Accatyyc 14

@Accatyyc、私は同じ問題を抱えているようです。デキューするのに十分なセルがない場合は少し遅れます。3〜4個のセルがデキューされると、スクロールはスムーズになります。セルをプリロードしてセルをデキューし、スクロール時にNIBファイルをロードしない方法はありますか?
Tiois、

@Tiois確かにあります。セルをデキューする古い方法を使用する必要があります(クラス/ニブを登録しないでください。ただし、dequeueCellWithIdentifier:がnilを返す場合は作成してください)。この方法では、テーブルビューが存在する前にセルのセットを作成できます。たとえば、前に20個のセルを作成できます。次に、cellForRowAtIndexPath:で新しいものを作成する代わりに、最初に自分のキャッシュからそれらが空になるまでプルします。
Accatyyc 2016

UICollectionViewを使用していますが、同じ問題に直面しています。私のカスタムセルnibファイル。垂直UIstackView内でUIwebViewやUIImageViewを含むいくつかのサブビューを使用しています。リストをスクロールすると、再利用されたセルのサイズを再調整するのにかなりの時間がかかり、スクロールがぎこちなく見えます。
Mansuu .... 2017

40
  1. をサブクラス UITableViewCell化する場合は、Nibを使用せず、代わりにコードで記述してください。Nibファイルをロードするよりもはるかに高速です。
  2. 画像を使用している場合は、それらをキャッシュしていることを確認してください。ファイルごとに複数回ロードする必要はありません(メモリがあれば、画像が占めるスペースの量に驚かれるでしょう)。
  3. できるだけ多くの要素を不透明にします。同様に、透明度のない画像を使用しないでください。

3
心配しないで...それは荒らしでした。すばらしい答えです!
Steav

79
反対票は、おそらく「ペン先を避ける」がパフォーマンスを改善するための悪いアドバイスであるためです。セルを再利用している場合、スクロールしても、セルはペン先からまったく再構築されません。
Steven Fisher

6
コブと愛の研究に基づくと、ニブの速度は同等、または少し速いです。cocoawithlove.com/2010/03/...
MaxGabriel

たとえば、高速スクロール中に、テーブルのセルの割り当てと割り当て解除を行うと、Nibを使用する@Steven Fisherが遅くなる可能性があります。
Sound Blaster 2013

3
セルの構築中は、NIBの使用が遅くなることがあります。セルの再利用を使用している場合、画面を埋めるために割り当てられているセルは十分です。たとえば、せいぜい10です。スクロールしているときは、セルは作成されません。それらは単に再利用され、割り当て解除や再割り当てはされません。そしてもちろん、割り当てを解除するコストはありません。いいえ、これは正しくありません。
Steven Fisher

34

トゥイーティーの背後にいる開発者は、これについて広範囲に記述しており、そのアプリでそれがどのように行われたかを示すコードをいくつか持っています。基本的に、彼/彼女はテーブルセルごとに1つのカスタムビューを推奨し、手動で描画します(他のオプションの中で、Interface Builderでサブビューするのではなく)。

高速スクロールイントゥイーティー付きウィットビュー

また、AppleはTableViewSuiteチュートリアルでTableViewの独自のサンプルコードを更新しました(おそらくこれに対応していますか?)

TableViewSuite


1
これは素晴らしいソリューションです。UIButtonをcellViewに追加するにはどうすればよいですか?drawRectメソッドで描画されていますか?
Sukitha Udugamasooriya

1
@beno、リンクが壊れているようです(最初のリンク)。元の記事を手に入れるチャンスはありますか?
apouche 2012

3
元の記事はここで読むことができます:web.archive.org/web/20100922230053/http://blog.atebits.com/2008/...
jverdi

オリジナルバージョンが存在しないため、Webアーカイブへのリンクを追加
Ralph Willgoss 2013

1

UITableViewスクロールの#1パフォーマンスキラーは、任意のセルビューレイヤーにシャドウを描画するため、スクロールパフォーマンスが重要な場合は、基本的にメインスレッドの速度が低下しない限り、シャドウを実行しないでください。

受け入れられた答えのどれも影と層について言及しなかったので、これは言われる必要があると思いました。:+)


6
問題が影である場合は、この2行のコードを追加し、すべてが完全に機能します。self.layer.shouldRasterize= YES; self.layer.rasterizationScale = UIScreen.mainScreen.scale;
PedroRomão2015

0

UITableViewスクロールのパフォーマンスに関する問題は、すでに他の回答で説明されている手法を使用して解決できます。ただし、パフォーマンスの低下は、本質的に誤りのある、または反復的なものによって引き起こされることがよくあります。

UITableViewセルを再利用するという事実と、各セルが独自のイメージを必要とする可能性があるという事実により、ソリューションは少し複雑になります。一般的な方法でそれがどのように解決されているかから、ここで注意すべき点を要約します:

  1. REST /データベースから-データソースにデータをロードします。この手順はバックグラウンドで行う必要があり、最終的にはGCDキューとともにdispatch_asyncを使用します。
  2. 関連するデータモデルオブジェクトを作成して初期化し、配列内に配置する
  3. [tableView reloaddata]
  4. 内部cellForRowAtIndexPathに、配列の正しいデータモデルオブジェクトからデータ(テキスト)を設定するコードを含めます。
  5. 画像もURLの形式になっている可能性があるため、テーブルビューでセルを再利用するため、この手順は少し風変わりな場合があります。中心となるのは、非同期キューを使用してデバイスキャッシュ/ URLから画像をもう一度読み込み、それをcell.imageに設定します(セル画像のプロパティは何でもかまいません)。

問題を回避するには、テーブルビュー内の画像の遅延読み込みに関するこのチュートリアルを参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.