3

我有一个使用 MKMapView 的简单 iphone 应用程序。它有一个分段控件,可以调整区域以缩放(街道、社区、城市、州、世界)。它工作正常,但如果我缩小到州级并回到街道,我注意到中心点已经移动。

以下是在区域更改之前和之后调用的两个委托方法,以及由分段控件调用的 changeZoom 方法:

- (void)mapView:(MKMapView *)mView regionDidChangeAnimated:(BOOL)动画
{
 MKCoordinateRegion region = [mapView region];

 NSLog(@"Region DID 改变。中心现在是 %f,%f, Deltas=%f,%f",
    region.center.latitude, region.center.longitude,
    region.span.latitudeDelta, region.span.longitudeDelta);
}

- (void)mapView:(MKMapView *)mView regionWillChangeAnimated:(BOOL)动画
{
 MKCoordinateRegion region = [mapView region];

 NSLog(@"区域会改变。中心现在是 %f,%f, Deltas=%f,%f",
    region.center.latitude, region.center.longitude,
    region.span.latitudeDelta, region.span.longitudeDelta);
}


- (IBAction)changeZoom:(id)sender
{
 UISegmentedControl *sc = (UISegmentedControl *)sender;

 浮动英里范围= 1;

 NSLog(@"changeZoom 调用。MapView 当前是 Center=%f,%f Deltas=%f,%f",
    mapView.region.center.latitude, mapView.region.center.longitude,
    mapView.region.span.latitudeDelta, mapView.region.span.longitudeDelta);

 开关 ( [sc selectedSegmentIndex] )
 {
  案例 0: /* 街道 */
   英里范围=1;
   休息;
  案例 1: /* 引擎盖 */
   英里范围=2;
   休息;
  案例 2: /* 城市 */
   英里范围=30;
   休息;
  案例 3: /* 状态 */
   英里范围=500;
   休息;
  案例 4: /* 世界 */
   英里范围=4000;
   休息;
  默认值:/* 错误 */
   NSLog(@"从 UISegmentedControl 中选择的未知段!!!!!!!!!!!!!!!");
   返回;
   休息;
 }

 originalZoomCenter = mapView.region.center;
 MKCoordinateRegion 区域;
    region = MKCoordinateRegionMakeWithDistance(originalZoomCenter, mile_range/MILES_PER_METER, mile_range/MILES_PER_METER);
    region = [mapView regionThatFits: region];

 NSLog(@"调用 setRegion Center=%f,%f Deltas=%f,%f",
    region.center.latitude, region.center.longitude,
    region.span.latitudeDelta, region.span.longitudeDelta );

    [mapView setRegion:区域动画:YES];

 NSLog(@"setRegion Center=%f,%f Deltas=%f,%f",
    mapView.region.center.latitude, mapView.region.center.longitude,
    mapView.region.span.latitudeDelta, mapView.region.span.longitudeDelta);
}

如果我运行该应用程序,它以我当前位置的街道缩放级别开始,然后单击以缩小到状态级别并返回到街道级别,我会在控制台中获得以下输出:

地区将会改变。中心现在是 30.145127,-40.078125,Deltas=151.851332,225.000000
区域 DID 发生变化。中心现在是 37.331676,-122.030725, Deltas=0.024842,0.027466
更改缩放调用。MapView 当前为 Center=37.331676,-122.030725 Deltas=0.024842,0.027466
调用 setRegion Center=37.331676,-122.030725 Deltas=12.708100,14.062500
地区将会改变。中心现在是 37.331676,-122.030725, Deltas=0.024842,0.027466
在 setRegion Center=37.331676,-122.030725 之后 Deltas=0.024842,0.027466
区域 DID 发生变化。中心现在是 37.335224,-122.036133, Deltas=12.707505,14.062500
更改缩放调用。MapView 当前为 Center=37.335224,-122.036133 Deltas=12.707505,14.062500
调用 setRegion Center=37.335224,-122.036133 Deltas=0.024841,0.027466
地区将会改变。中心现在是 37.335224,-122.036133, Deltas=12.707505,14.062500
setRegion Center=37.335224,-122.036133 之后 Deltas=12.707505,14.062500
区域 DID 发生变化。中心现在是 37.335224,-122.036133, Deltas=0.024841,0.027466

因此,我在代码中进行的所有调用都按预期进行,并且中心没有改变,但是当我监视 MKMapViewDelegate 方法 regionDidChangeAnimated 时,我看到中心被移动了。如果我在那里设置断点,我会看到一个如下所示的堆栈:

#0 0x00034c4c in -[MapViewController mapView:regionDidChangeAnimated:] at MapViewController.m:209
#1 0x01fbf7bf in -[MKMapView _didChangeRegionMidstream:]
#2 0x003e11f5 in -[UIView(Gestures) animator:stopAnimation:]
#3 0x003743be in -[UIAnimator stopAnimation:]
#4 0x00374154 in -[UIAnimator(Static) _advance:]
#5 0x0264d719 在 HeartbeatTimerCallback
#6 CFRunLoopRunSpecific 中的 0x01d28ac0
#7 0x01d27c48 在 CFRunLoopRunInMode
#8 GSEventRunModal 中的 0x0264a78d
#9 0x0264a852 在 GSEventRun
#10 0x00307003 在 UIApplicationMain
#11 0x00002194 在 main.m:14

这并不能真正帮助我理解为什么中心会移动。我在模拟器和设备上都运行过它,这让我有点发疯。

如果有人对导致中心转移的原因有任何见解,我将不胜感激。

4

1 回答 1

3

根据我的经验,在region使用公共 API 或 UI 事件以编程方式修改其区域后,地图的属性会被重新计算。

通过缩小,您会失去地图中心的精度(一个像素覆盖更大的区域)。然后,在使用 设置区域后setRegion:[animated:],(因此计算的)map.region可能与 setRegion 中给出的区域不同。这可以解释你得到的增量。

为了解决您的特定问题,我宁愿在每次用户移动地图时存储地图的中心,并使用存储的值进行缩放而不是信任map.region.center

于 2012-01-17T01:08:09.887 回答