2011年12月12日月曜日

[Titanium AdventCalendar 2011/12日目] バグ図鑑+optionPickerDialog.js


Titanium AdventCalendar 2011の12日目のエントリーです。
@astronaughtsさん! いつもお世話になっております。

好きなAPIは Titanium.UI.3DMatrixです。
やっと言えた! (ずっと言いたかった)

今回は、
  • Titaniumをやってて困ったところを、ホラー調でご紹介します(先に謝っておきます、申し訳ございません)
  • Titanium.UI.OptionDialog のPicker版、optionPickerDialog.jsをご紹介します
モジュールについて書こうと思ってましたがこんなことに...

予めお断りしておくと、私はiOSでしかTitaniumを使っておらず、Androidについては
確認等してませんのであしからず。

では、参りましょう...

その一. 凄惨!Titanium.UI.Pickerのクラッシュ!
SDK :  SDKというかiOS 4.3で確認、iOS 5.0では出現せず
JIRA: #TIMOB-5489

こんなコードをiOS 4.3で動かすと...
var window = Ti.UI.createWindow();
var picker = Ti.UI.createPicker({
 top:480
});
window.add(picker);

var button = Ti.UI.createButton({
 title:'push...', 
 width:80, 
 height:30
});
window.add(button);

var data = [];
data[0]=Ti.UI.createPickerRow({title:'Bananas',custom_item:'b'});
data[1]=Ti.UI.createPickerRow({title:'Strawberries',custom_item:'s'});
data[2]=Ti.UI.createPickerRow({title:'Mangos',custom_item:'m'});
data[3]=Ti.UI.createPickerRow({title:'Grapes',custom_item:'g'});

picker.selectionIndicator = true;
button.addEventListener('click', function(){
 picker.add(data);
 picker.animate({ top:240, duration:500 });
});
window.open();
もう二度と帰って来れなくなりますよ...
2011-12-11 16:35:59.776 TiAdventCalendarDemo[10891:13a03] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 0 beyond bounds for empty array'
window.add()する前にpikcer.add()すれば助かります。

その二. 暗黒のTitanium.Media.openPhotoGallery...
SDK :  1.7.5 (多分1.7.5以前も...)
Appcelerator Q/A:http://developer.appcelerator.com/question/121924/ios-memory-warnings-unloads-app-black-screen-of-death

この画面から...
Titanium.Media.openPhotoGallery()を呼んで...
メモリ警告を発生させて...

Cancelを押して戻ってみると...
キャァーッ!!!目が...目が!!!

SDK 1.8になると多分もう出会えません。(1.8 CIでは治ってました)

その三. Titanium.UI.Toolbarで歪む空間...
SDK :  1.7.5 (多分1.7.5以前も...)
Appcelerator Q/A:http://developer.appcelerator.com/question/119529/toolbar-button-image-distortion

こんなコードを書いて...
var toolbarButton1 = Ti.UI.createButton({
 image:'photo_gallery.png'
});
var toolbarButton2 = Ti.UI.createButton({
 image:'filter.png'
});
var toolbarButton3 = Ti.UI.createButton({
 image:'tiltshift.png'
});
var toolbarButton4 = Ti.UI.createButton({
 image:'save.png'
});
var flexible = Ti.UI.createButton({
    systemButton:Ti.UI.iPhone.SystemButton.FLEXIBLE_SPACE 
});
var toolbar = Ti.UI.createToolbar({
 barColor:'#000',
 items:[toolbarButton1, flexible, toolbarButton2, flexible, toolbarButton3, flexible, toolbarButton4],
 bottom:0
});
window.add(toolbar);
デバイスの向きを横にしてみましょう...
私は今どこにいるの...

...ええと、ちゃんと表示したい場合はbackgroundImageプロパティに'none'を設定してあげるか、そもそも表示したい画像をbackgroundImageプロパティに設定してあげましょう。

楽しいですね!では、次。

Titanium.UI.optionPickerはご存知ですか?


こんなやつです。(doc-jaからコードを拝借しました)
画面の下からヌゥーっと出てきます。

選択肢が少ない場合はいいのですが、選択肢が多い場合は少し困ってしまいます。

そんなとき、optionPickerDialog.jsの出番です。
(どこかのブログで書かれていたのをきっかけで知ったのですが、どこだったかな...)

コードはこちら http://www.pastie.org/1494046

Bart Lewisさんという方が書いてくださったもので、使い方はこんな感じです。
// まあ、こうしないと始まりませんね
Ti.include('optionPickerDialog.js');
// titleとvalueというプロパティを持ったオブジェクトの配列を
// optionPickerDialog.setData()で設定します。
var data = [
    { title:'A', value:1 },
    { title:'B', value:10 },
    { title:'C', value:100 }, 
];
optionPickerDialog.setData(data);
// closeイベントで、doneかcancelか分かります。
// また、doneの場合、選択した内容にアクセス出来ます。
optionPickerDialog.addEventListener('close', function(e){
 if (e.done==true && e.selectedRow){
  alert(e.selectedRow.value);
 }
}); 
// open()でダイアログが下からヌゥーっと出ます
optionPickerDialog.open();
open()でこんなのが出てきます。













気をつけないといけないのは、optionPickerDialog.jsでTi.UI.currentWindowが使われています。
シングルコンテキストな場合は、ちょっと修正してあげないといけません。
(私はとりあえずcurrentWindowというグローバル変数を使うようにしました)

また、2つほどバグがありました。

  1. iOS 4.3でクラッシュしちゃう(上記のバグですね)
  2. デバイスを横向きにしたときのツールバーの位置がちょっとおかしい
勝手に修正してしておきました。コードはこちら http://pastie.org/2999293

以上、まとまりのないエントリーでしたが、読んでいただきましてありがとうございました。
明日は、@h5y1m141さんです。よろしくお願いします!