MapViewが初期化時にregionChangedを何度も呼び出す
アプリを再起動した際にMapViewの以前表示していた位置を表示したいが、TitaniumのMapViewが初期化時にregionChangedを何度も呼び出すという謎の挙動をするためにうまくいかない。
この挙動は本家のQ&Aにも報告されている。
そういう状況を無理矢理回避したメモ。
基本的には
- Regionが変更されるたびにアプリケーションプロパティに記録する
- 再起動の際にアプリケーションプロパティに記録してあるRegionを設定する
- 記録してあるRegionが無ければデフォルトのRegionを設定する
といったシンプルなことをしたい。
しかしながらMapViewの初期化途中にlatitudeDeltaが何度も変更されるため、その中途半端なRegionがセットされてイヤンなかんじになってしまう。
そこで以下のような処理を施す。
- Regionの変更を記録するのはマップ表示後1秒してから(initCompleteというフラグを定義して、1秒後にそのフラグを立てる)
- 1秒経っていない時にregionChangedが発生したら強制的に記録してあるRegionに戻す
- 戻した際にregionChangedが発生して無限ループ(といっても1秒間だけだが)するのでRegionの値が記録してあるRegionならsetRegionを呼び出さない
なんというその場しのぎ。
しかし仕方がない。
コード例
MapHelperは独自に定義したクラス。内容が気になる人は以前のユニットテストの記事参照。
Ti.include("map_helper.js");
var mapHelper = new MapHelper();
var latestRegion = mapHelper.loadLatestRegion();
var mapView = Titanium.Map.createView({
mapType: Titanium.Map.STANDARD_TYPE,
region: latestRegion,
animate: true,
regionFit: true,
userLocation: true,
annotations: []
});
mapView.initComplete = false;
setTimeout((function() {
mapView.initComplete = true;
}), 1000);
Ti.UI.currentWindow.add(mapView);
mapView.addEventListener('regionChanged', function(e) {
if (mapView.initComplete) {
mapHelper.saveLatestRegion(e);
}
if (!mapView.initComplete && e.latitudeDelta !== latestRegion.latitudeDelta) {
mapView.setRegion(latestRegion);
}
});
Titaniumはたまに変なはまりどころがある。
2011/01/26追記
ソースが間違っていたので修正。
CoffeeScriptを手で直したもんだからvar付けてなかったりとか括弧足りなかったりとかしてた。
