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