HOME » Natsu note » 古い投稿 » [iOS] TableView スクロールパフォーマンスの改善

[iOS] TableView スクロールパフォーマンスの改善 2010/10/22/|古い投稿,

この記事は情報が古い可能性があります。参照する際にはご注意ください。

データベースを用いたアプリ一般に関していろいろと勉強しようと思い、”Professional iPhone and iPad Database Application Programming“という本を読み始めた。この本なかなかよい。データドリブンのアプリケーションを設計する際のポイントが結構幅広く書かれている。本の紹介は別途することにして、今回はTableViewのパフォーマンスを「簡単に」改善できるかもしれない方法をご紹介。

透過性のビューを極力使わない

 

UITableViewCellにはデフォルトで4種類のスタイルが用意されているが、これでは不十分な場合、自分でセルをカスタマイズすることになる。

 

その方法はいろいろあるが、中でも簡単なのはセルのcontentViewに別のビューをペタペタと貼付けていく方法だ。サブビューの作成と追加はTableViewDataSourceのメソッドtableView:cellForRowAtIndexPath:で行ってもよいし、UITableViewCellのサブクラスを作成しその中で行うことも可能だ。もちろんインターフェイスビルダー(IB)を使えば簡単に見栄えを調整しつつ複数のサブビューを持つセルを作成することができる。

 

このような独自のセルを生成する際には気をつけたいことがある。それは、ビューの透過性。

透過レイヤーの統合は負荷がかかり、透過性のサブビューはスクロールパフォーマンスを低下させる。したがって、透過性のビューはできるだけ用いないほうがよいのだ。以下は具体的に気をつけたい点。

セル自体の透過性

UITableViewCellはUIViewのopaqueプロパティを継承している。デフォルトではYESなので透過していない。どうしても変更する必要がない限りここは変更しないべきである。

サブビューの透過性

独自にビューを作成して追加する場合、これらのビューも透過していない方がよい。なお、異なる背景色もパフォーマンスに影響するため、背景色はできるだけ統一しておいたほうがよい。

PNGを使う場合

UIImageクラスのクラスメソッドimageNamed:でpng形式の画像を表示する際は、オリジナルのpng画像を作成する際にAlphaレイヤーを含まないように作っておくとよい。Alphaレイヤーが含まれている場合、UIImageViewのopaque値に関係なくレイヤーの統合処理が発生する。

IBを利用する際の注意点

Instrumentsを利用して透過ビューを確認(詳細は以下)していく過程で気がついたのだが、IBで作成するUILabelのopaqueはデフォルトでNOになっている。これは注意が必要。

Instrumentsを利用した透過ビューの確認

これははじめて知ったのだが、Instrumentsを利用して簡単に透過ビューを確認することができる。

Instrumentsを開きライブラリからCore Animationを追加。左下のDebug Optionで「Color Blended Layers」にチェックを入れる。

Instruments CoreAnimation BlendedLayer

これで、デバイス上の画面に色がつく。

緑色の部分は単レイヤーの部分。赤くなっている部分は統合されているレイヤーだ。つまり、左のようになっていればOK。右のようになっている場合は透過性のビューが多いため要注意ということになる。

Instruments opaque YESInstruments opaque NO

簡単にチェックできるので、スクロールのパフォーマンスに問題を抱えている方は試してみては。

セルの内容をdrawRectで直接描画

追加したサブビューの透過性や背景色等を考慮してもまだパフォーマンス問題がある場合、次の手はdrawRectを使った直接描画だ。contentViewと同サイズのビュー(UIViewのサブクラス)をひとつ作り、UILabelやUIImageViewを利用する代わりにdrawRectで直接描画する。

たとえば、サブクラスの中のdrawRectはこんな感じになる。上の方法でUILabelやUIImageViewに追加していた文字列や画像をそのまま描画するというわけだ。

- (void)drawRect:(CGRect)rect {
    // Draw the texts
    [theProduct.name drawAtPoint:CGPointMake(45.0,0.0) 
                        forWidth:120 
                        withFont:[UIFontsystemFontOfSize:18.0] 
                     minFontSize:12.0 
                  actualFontSize:NULL
                   lineBreakMode:UILineBreakModeTailTruncation 
              baselineAdjustment:UIBaselineAdjustmentAlignBaselines]; 
    .......... 
    // Draw the images 
    NSString *filePath = [[NSBundlemainBundle] pathForResource:theProduct.image ofType:@"png"];
    UIImage *image = [UIImageimageWithContentsOfFile:filePath];
    [image drawInRect:CGRectMake(0.0, 0.0, 40.0, 40.0)];
}

こんな感じで直接ビューを描画すればパフォーマンス問題がかなり改善されるはず。

データベースを利用してアプリケーションを作成する以上、どうしてもそのデータを表示する必要がある。そのために一番適しているのがTableViewなので、TableViewを使いこなせるようにならなければ、なかなかアプリケーションの品質アップは難しい。細かいところまで配慮できるよう日々精進。

なお、ここにまとめた内容は、”Chapter 3: Optimizing TabeView Performance”の内容であり、上記のスクリーンショットで利用したアプリケーションやコードの一部は本の中に出てくるサンプルを使っている。コードは出版社のサイト(http://www.wrox.com/WileyCDA/WroxTitle/Professional-iPhone-and-iPad-Database-Application-Programming.productCd-0470636173,descCd-DOWNLOAD.html)からダウンロード可能。


完全に余談ですが、私はKindleバージョンを購入。アメリカ以外の国ではまだ発売されていないうちに購入できてちょっと得した気分でした。笑

質問などなどありましたら、いつものようにツイッター(@natsun_happy)でお願いします。