5

マップの境界が変更されたときにいくつかのイベント(基本的には外部サーバーへのクエリ)を発生させるiPhoneMapKitコードに取り組んでいます。解決できないと思われるエッジケースが1つあります。ユーザーが新しい住所を入力すると、setRegionを使用してその場所にズームインし、その後、地図の境界を計算して、それらの座標を使用して外部サーバーにクエリを実行します。私はいつもsetRegionと呼んでいますが、起動しない場合が1つあります。つまり、ユーザーが魔法のように地図の現在の中心にあるまったく同じ住所を選択したとき、その地図がまったく同じ地域にズームされたときです。もちろん、この可能性はまれですが、次のコードで簡単に実現できます。

CLLocation *centerOfMap = [[CLLocation alloc] initWithLatitude:mapView.centerCoordinate.latitude longitude:mapView.centerCoordinate.longitude];
mySearchLocation.searchLocation = centerOfMap;

//Recenter and zoom map in on search location
MKCoordinateRegion region =  {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center = mySearchLocation.searchLocation.coordinate;region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[self.mapView setRegion:region animated:YES];

これは、ユーザーが現在のマップの中央にピンをドロップし、それに基づいてサーバーにクエリを実行できるようにすることと同じです。残念ながら、コードロジックは地域の変更に依存しているため(ユーザーがマップを簡単にパンでき、更新ボタンを明示的に押す必要がないようにしています)、回避策が必要です。setRegionが呼び出されたのに、regionWillChange/regionDidChangeが起動されないことを確認するにはどうすればよいですか。関数をなんらかの方法でオーバーライドできますか?

編集:最初の回答にコメントしたように、次のコードを使用して、リージョンが変更されない場合を検出しようとしました。

//Recenter and zoom map in on search location
MKCoordinateRegion region =  {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center = mySearchLocation.searchLocation.coordinate;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
region = [mapView regionThatFits:region]; //Not sure if this is necessary

NSLog(@"diff in latitude of center %f", (mapView.region.center.latitude - region.center.latitude));
NSLog(@"diff in longitude of center %f", (mapView.region.center.longitude - region.center.longitude));
NSLog(@"diff in latitude span %f", (mapView.region.span.latitudeDelta - region.span.latitudeDelta));
NSLog(@"diff in longitude span %f", (mapView.region.span.longitudeDelta - region.span.longitudeDelta));

[self.mapView setRegion:region animated:YES];

残念ながら、searchLocationを現在の地図の中心に設定すると、次の結果が得られます。

diff in latitude of center 0.000000
diff in longitude of center 0.000016
diff in latitude span -0.000000
diff in longitude span 0.000000

場合によってはエラーがわずかに異なりますが、一般的に言えば、このsetRegion以上のようにリージョンがわずかに異なる場合でも、regionDidChangeは発生しません。誰かが理由を説明できますか?または、これを適切に検出する方法を教えてください。注:mapView.centerCoordinateも試してみましたが、同様のエラーが発生し、領域が変更されない場合のみ知りたいです(centerCoordinateが同じ場合、ズームレベル/領域は異なる可能性があります)。

4

3 に答える 3

0

これは、私にとってはうまくいくと思われるハッキングされた回避策です。

MKCoordinateRegion currentRegion = mapView.region;

// Capture the instances where setRegion will not be fired
BOOL regionLatitudeSame = (int)(currentRegion.center.latitude*1000000) == (int)(region.center.latitude*1000000);
BOOL regionLongitudeSame = (int)(currentRegion.center.longitude*1000000) == (int)(region.center.longitude*1000000);
BOOL regionSame = regionLatitudeSame && regionLongitudeSame;
if (regionSame)
{
    // Safe to assume that regionWillChange/regionDidChange WON'T be called
}

お気づきかもしれませんが、私は、小数点第 6 位以降の精度は (最大 11 mmまで) 小さすぎて、マップ上で視覚的な変更が必要であるとは限りません (最高のズーム レベルであっても)。

于 2012-09-30T11:14:41.473 に答える
0

マップを設定するポイントが現在の中心になることを検出した場合、新しいマップの場所を設定しているコードから手動で regionWill/Did change を呼び出してみませんか?

于 2010-01-18T20:20:26.873 に答える