私も、この非常に厄介なバグにイライラしました。
締め切りが迫っているので、回避策の実装に多くの時間を費やすことはできません。
最大ズームで MKUserTrackingModeFollowWithHeading にとどまることができましたが、ユーザーの場所の注釈「ピン」はまだかなり大きく揺れており、いくつかのエッジケースでは、MKUserTrackingModeFollow にキャンセルされていました。
私が最初にしたことは、次のように、 regionDidChangeAnimated: デリゲート メソッドで BOOL フラグを使用して強制的に修正することでした。
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
NSLog(@"regionWillChangeAnimated:");
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
NSLog(@"regionDidChangeAnimated:");
[self forceCorrectUserTrackingMode];
}
- (void)forceCorrectUserTrackingMode {
if (shouldFollowWithHeading == YES && ([mapView userTrackingMode] != MKUserTrackingModeFollowWithHeading) ) {
NSLog(@"FORCE shouldFollowWithHeading! - setUserTrackingMode:MKUserTrackingModeFollowWithHeading");
[self.mapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:YES];
} else if (shouldFollowWithHeading == NO && ([mapView userTrackingMode] != MKUserTrackingModeNone) ) {
NSLog(@"FORCE should NOT FollowWithHeading - setUserTrackingMode:MKUserTrackingModeNone");
[self.mapView setUserTrackingMode:MKUserTrackingModeNone animated:YES];
}
}
これは実際にはかなり近づいたのですが、十分に信頼できるものではありませんでした。前述のように、締め切りまでに他の機能を優先することを考える必要があったため、最終的には次のようになりました。
まず、MKMapKit のズーム カテゴリのコードを取得しました: http://troybrant.net/blog/2010/01/set-the-zoom-level-of-an-mkmapview/
次に、訪問者がそのブログのコメントで提供したこのメソッドを含めました。
- (int) getZoomLevel {
return 21 – round(log2(mapView.region.span.longitudeDelta * MERCATOR_RADIUS * M_PI / (180.0 * mapView.bounds.size.width)));
}
最後に、ズームレベルとバグの発生を少し試行錯誤してテストした結果、次の「回避策」にたどり着きました。
CLLocationCoordinate2D userLocation_CenterCoordinate = CLLocationCoordinate2DMake([locationManager location].coordinate.latitude, [locationManager location].coordinate.longitude);
int currentZoomLevel = [MKMapView getZoomLevelForMapView:mapView];
int newZoomLevel = 17;
if (currentZoomLevel > 17) {
NSLog(@"Adjusting mapView's zoomLevel from [%d] to [%d], also centering on user's location", currentZoomLevel, newZoomLevel);
[mapView setCenterCoordinate:userLocation_CenterCoordinate zoomLevel:newZoomLevel animated:NO];
} else {
NSLog(@"Centering on user's location, not adjusting zoom.");
[mapView setCenterCoordinate:userLocation_CenterCoordinate animated:NO];
}