2012年5月7日月曜日

SDK 2.0.1でも描画問題への対処は必要(3)

Titanium SDK 2.0.1GA2で、描画関係のバグが解消されているか調べる話の続きです。iPhone用アプリの開発で経験した、画面を回転させたとき、ImageViewやLabelが変な位置に描画される問題を取り上げます。前の投稿で直っていると書きましたが、対処方法を実施しても消えなかったバグが出なくなっただけで、対処方法を不要するレベルで直っているかは不明でした。そこを調べたので報告します。

 

まずはバグの内容を。画面を回転させたときにアニメーションで表示されますが、縦横表示で同じViewを使い、View上のUI部品の位置を回転時に変更すると、設定したtopやleftの値とは全然違う位置に表示される問題です。発生する条件ですが、複数のImageViewの位置を変更させると起こるようです。単に位置が変になるだけではなく、本来なら下に隠れているImgeViewの一部も表示されてしまいます。対処方法は、次のような形でした。見えているUI部品だけの位置を変更し、下に隠れているUI部品はsetTimeoutで遅延させて変更する方法です。この対処方法でほとんど解消したのですが、たまに実機でのみ、一部のLabelが変な位置に表示されます。

以上にような状態のまま2.0.1GA2で再ビルドすると、実機でも変な位置の表示が解消されました。その点では、問題が解消されたといえます。しかし、本来なら特別な対処方法(一部の設定を遅延させる)を使わなくても、プロパティで指定した位置に表示すべきものです。それが直っているかどうか、シミュレータと実機の両方で確認してみました。

 

まず、対処方法を加えたコードです。画面が回転したときに呼び出される関数として作ってあります。表示中のUI部品だけは位置プロパティを変更し、残りのプロパティ変更は遅延した別関数として作りました。このような形で作ると、シミュレータ上ではバグが完全に消えました。ただし実機でのみ、少しバグが出ます。

// 1つだけImageViewを変更する
function changeOrientF() {
    var orient = Ti.Gesture.orientation;
    if (orient == Ti.UI.PORTRAIT || orient == Ti.UI.UPSIDE_PORTRAIT) {
        imgView1.height = 240;
        imgView1.width = 320;
        ...
    } else if (orient == Ti.UI.LANDSCAPE_LEFT || orient == Ti.UI.LANDSCAPE_RIGHT) {
        imgView1.height = 320;
        imgView1.width = 427;
        ...
    }
    setTimeout(changeOrient2F, 200); // 0.2秒後に動かす
}
// 残りのImageViewを、時間差を付けて変更する
function changeOrient2F() {
    var orient = Ti.Gesture.orientation;
    if (orient == Ti.UI.PORTRAIT || orient == Ti.UI.UPSIDE_PORTRAIT) {
        imgView2.height = 240;
        imgView2.width = 320;
        ...
    } else if (orient == Ti.UI.LANDSCAPE_LEFT || orient == Ti.UI.LANDSCAPE_RIGHT) {
        imgView2.height = 320;
        imgView2.width = 427;
        ...
    }
} 

このコードを、本来の形に戻します。遅延する関数として2つに分けるのではなく、すべてのプロパティ変更を一緒にして、1つの関数として作ります。具体的なコードは、次のようになります。

// すべての変更を1つにまとめる
function changeOrientF() {
    var orient = Ti.Gesture.orientation;
    if (orient == Ti.UI.PORTRAIT || orient == Ti.UI.UPSIDE_PORTRAIT) {
        imgView1.height = 240;
        imgView1.width = 320;
        ...
        imgView2.height = 240;
        imgView2.width = 320;
        ...
    } else if (orient == Ti.UI.LANDSCAPE_LEFT || orient == Ti.UI.LANDSCAPE_RIGHT) {
        imgView1.height = 320;
        imgView1.width = 427;
        ...
        imgView2.height = 320;
        imgView2.width = 427;
        ...
    }
}

ご覧のように、難しい変更ではありません。バグが解消していれば、一部のプロパティ変更を遅延させなくても、正常な位置に表示されるはずです。

 

さて実際に動かした結果ですが、シミュレータでも実機でも、変な位置に表示されるバグは出ませんでした。ImageViewもLabelも、プロパティで設定した位置に表示されます。動作中のいろいろなタイミングでiPhoneを回転しましたが、途中の状態はさておいて、最後には正常な位置で表示しました。アプリのアニメーション中に回転アニメーションが加わっても、いつも正常な位置に収まります。2.0.1GA2では、バグが解消されているようです。

画面回転での表示バグは、いろいろな対処方法を試しましたが、どうしても解決しなかったものでした。SDKのバージョンアップで解消され、本当に良かったです。バグが消えたことで、特別な対処方法を用いる必要がなくなりました。

 

ここまで3回の投稿を整理すると、2.0.1GA2で対処が必要な描画問題は、フラッシュバック症状だけになりました。これは前から対処方法を見付けていますから、ぜんぜん大丈夫です。2.0.1GA2では対処方法をpostlayoutイベント処理で実現しますが、非常に簡単な変更でした。この1つだけで大丈夫になったということは、Titanium SDKのレベルアップではないでしょうか。まさに意味のあるバージョンアップですね。

2.0.1が安定したバージョンになれば、もう安心して公開できます。画像がメインのアプリなので、あとは画像とテキストの制作待ちですが、SDKの安定バージョンが出る頃には、制作も終わっているでしょう。めでたし、めでたし。

0 件のコメント:

コメントを投稿