5

我正在研究一些 iPhone MapKit 代码,当地图边界发生变化时会触发一些事件(基本上是对外部服务器的一些查询)。有一个边缘情况我似乎无法解决。当用户输入新地址时,我使用 setRegion 放大该位置,然后计算地图的边界并使用这些坐标查询我的外部服务器。我总是调用 setRegion 但是,有一个边缘情况它不会触发。也就是说,当用户神奇地碰巧选择了位于地图当前中心的完全相同的地址时,当该地图被缩放到完全相同的区域时。当然,这种可能性很少见,但使用以下代码很容易实现:

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

如果检测到将地图设置为当前中心的点,您为什么不直接从设置新地图位置的代码中手动调用 regionWill/Did change?

于 2010-01-18T20:20:26.873 回答
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
}

您可能已经注意到,我假设小数点后第六位的精度太微不足道(最高 11 毫米),以至于需要在地图上进行视觉更改(即使在其最高缩放级别)。

于 2012-09-30T11:14:41.473 回答
0

以下代码对我有用:

    let predictRect = mapView.convertRegion(mapView.regionThatFits(THE_REGION_YOU_WANT_TO_SET), toRectTo: mapView)

    if predictRect.origin.x.rounded() == 0 && predictRect.origin.y.rounded() == 0
        && predictRect.size.width.rounded() == mapView.bounds.width
        && predictRect.size.height.rounded() == mapView.bounds.height
    {
        debugPrint("setRegion same, will not trigger region change event")
    }
于 2017-04-18T16:41:41.620 回答