17

iPhone アプリが次のように閉じているときに、マップ領域をユーザーのデフォルトに保存しています。

MKCoordinateRegion region = mapView.region;
[[NSUserDefaults standardUserDefaults] setDouble:region.center.latitude forKey:@"map.location.center.latitude"];
[[NSUserDefaults standardUserDefaults] setDouble:region.center.longitude forKey:@"map.location.center.longitude"];
[[NSUserDefaults standardUserDefaults] setDouble:region.span.latitudeDelta forKey:@"map.location.span.latitude"];
[[NSUserDefaults standardUserDefaults] setDouble:region.span.longitudeDelta forKey:@"map.location.span.longitude"];

アプリが再び起動すると、Ш はそれらの値を同じ方法で読み戻して、ユーザーが前回とまったく同じマップ ビューを表示できるようにします。

MKCoordinateRegion region;

region.center.latitude  = [[NSUserDefaults standardUserDefaults] doubleForKey:@"map.location.center.latitude"];
region.center.longitude = [[NSUserDefaults standardUserDefaults] doubleForKey:@"map.location.center.longitude"];
region.span.latitudeDelta  = [[NSUserDefaults standardUserDefaults] doubleForKey:@"map.location.span.latitude"];
region.span.longitudeDelta = [[NSUserDefaults standardUserDefaults] doubleForKey:@"map.location.span.longitude"];

NSLog([NSString stringWithFormat:@"Region read  : %f %f %f %f", region.center.latitude, region.center.longitude, region.span.latitudeDelta, region.span.longitudeDelta]);

[mapView setRegion:region];

NSLog([NSString stringWithFormat:@"Region on map: %f %f %f %f", mapView.region.center.latitude, mapView.region.center.longitude, mapView.region.span.latitudeDelta, mapView.region.span.longitudeDelta]);

ユーザーのデフォルトから読み取ったリージョンは、(驚くべきことではありませんが) 保存したときとまったく同じです。保存されるものはマップから直接取得されるため、変換されることはありません。setRegion:メソッドでマップに戻しましたが、違います!

結果の例:

Region read  : 50.241110 8.891555 0.035683 0.042915<br>
Region on map: 50.241057 8.891544 0.050499 0.054932

なぜこれが起こるのか誰か知っていますか?

4

9 に答える 9

2

私も同じ問題を抱えていました。これは非常にイライラします。MKMapView のドキュメントは、データ型に関する一部の領域で正しくないようです。

領域パラメーターを (double) として設定すると、エラーが発生します。ただし、リージョン パラメータが (float) で渡された場合は、正しい動作が得られます。

だから試してみてください

MKCoordinateRegion region = {{0.0f,0.0f},{0.0f,0.0f}};

region.center.latitude = (float) [[NSUserDefaults standardUserDefaults] doubleForKey:@"map.location.center.latitude"];
region.center.longitude = (float) [[NSUserDefaults standardUserDefaults] doubleForKey:@"map.location.center.longitude"];
region.span.latitudeDelta = (float) [[NSUserDefaults standardUserDefaults] doubleForKey:@"map.location.span.latitude"];
region.span.longitudeDelta = (float) [[NSUserDefaults standardUserDefaults] doubleForKey:@"map.location.span.longitude"];

mapView.region = region;
于 2009-09-06T18:59:55.660 に答える
2

わかりましたので、私はこの問題にしばらく苦労してきました.Cruftyの理論に触発された効果的な回避策を思いついたと思います( MKMapViewは正しく保存されていない領域を表示します)。基本的に、マップ ビューが初期ロードを完了した後に NSUserDefaults から取得した値を使用してマップ ビュー領域を設定すると (「スナップ アウト」動作で完了)、マップ領域は期待どおりになります。 . 秘訣は、初期化されたマップ ビューの下流のどこかでアプリケーション コード内のフックを見つけることです。きれいではありませんが、私にとっては完璧に機能します。洞察を提供してくれたCruftyに感謝します。

于 2009-11-17T00:02:28.580 に答える
0

0.999 の代わりに 0.9 の乗算係数を使用すると、より大きな成功を収めることができました。それでも時々押し出されますが、目的のズームに近づくようです。私はそれを打ち負かしたと言うだけで、この問題を解決したいと思います! 笑

于 2011-06-22T01:28:34.137 に答える
0

これが機能することを確認できません。他の誰かがそうすることができますか?あなたが見ているのは、double を float に切り捨てた結果であると確信しています。場合によっては、これが私に起こったとき、スパンに 0.9999 を掛けて領域をリセットできることがわかりました。ただし、すべての地域ではありません。特に小規模なスパンでは、最大 20% も異なる場合があります。

于 2009-09-07T11:44:18.237 に答える
0

MKCoordinateRegion を適切にエンコードおよびデコードするための Swift 拡張機能を次に示します。

extension MKCoordinateRegion {

    var encode:[String: AnyObject] {
        return ["center":
                   ["latitude": self.center.latitude,
                   "longitude": self.center.longitude],
                "span":
                   ["latitudeDelta": self.span.latitudeDelta,
                   "longitudeDelta": self.span.longitudeDelta]]
    }

    init?(decode: [String: AnyObject]) {

        guard let center = decode["center"] as? [String: AnyObject],
            let latitude = center["latitude"] as? Double,
            let longitude = center["longitude"] as? Double,
            let span = decode["span"] as? [String: AnyObject],
            let latitudeDelta = span["latitudeDelta"] as? Double,
            let longitudeDelta = span["longitudeDelta"] as? Double
        else { return nil }


        self.center = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
        self.span = MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta)
    }
}

これはそれを使用する方法です:

// Save
NSUserDefaults.standardUserDefaults().setObject(mapView.region.encode, forKey: "mapRegion01")

// Restore
if let dict = NSUserDefaults.standardUserDefaults().dictionaryForKey("mapRegion01"),
    let myRegion = MKCoordinateRegion(decode: dict) {

    // do something with myRegion
}
于 2016-12-22T16:28:52.047 に答える
-1

InterfaceBuilder で MapView を設定する場合は、次のことを行わないでください。

_mapView = [[MKMapView alloc] init];

この init 行を削除するとすぐに、マップ ビューが突然、送信したすべての更新に適切に応答し始めました。alloc init を実行すると、実際にはどこにも表示されていない別のビューが作成されるのではないかと思います。画面に表示されるのは、ペン先によって初期化されたものです。しかし、新しいものを init に割り当てると、それは別の場所にあり、何もしません。

于 2013-11-26T04:50:57.467 に答える