我正在研究一些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是相同的,缩放级别/区域仍然可以不同)。
答案 0 :(得分:0)
为什么不直接调用regionWill /如果它检测到将地图设置为当前中心的点,则从设置新地图位置的代码手动更改?
答案 1 :(得分: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
}
正如您可能已经注意到的那样,我已经假设小数点后第六位的准确度太微不足道了(up to 11 mm),因为地图上需要进行视觉变化(即使在最高位置)缩放级别。。
答案 2 :(得分: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")
}