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付けてなかったりとか括弧足りなかったりとかしてた。