我已经在 iOS 6 和 iOS 7 beta 上使用一个简单的演示应用程序测试了这个问题。事实证明,地图视图实际上并不总是动画区域之间的过渡。这取决于区域之间的距离。例如,从巴黎到伦敦的过渡没有动画效果。但如果你先缩小一点,然后去伦敦,它就会变成动画。
文档说:
动画:如果您希望地图视图以动画方式过渡到新区域,请指定 YES,如果您希望地图立即以指定区域为中心,请指定 NO。
但正如我们所见,我们不能依赖动画。我们只能告诉地图视图过渡应该是动画的。MapKit 决定动画是否合适。它告诉代理过渡是否将在-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
.
为了在所有情况下始终如一地为区域变化设置动画,您需要首先为中间区域设置动画。设 A 为当前地图区域,B 为目标区域。如果区域之间有交集,您可以直接过渡。(将 转换MKCoordinateRegion
为 anMKMapRect
并用于MKMapRectIntersection
查找交点)。如果没有交集,则计算跨越两个区域的区域 C(使用MKMapRectUnion
和MKCoordinateRegionForMapRect
)。然后先去C区,regionDidChangeAnimated
再去B区。
示例代码:
MKCoordinateRegion region = _destinationRegion;
MKMapRect rect = MKMapRectForCoordinateRegion(_destinationRegion);
MKMapRect intersection = MKMapRectIntersection(rect, _mapView.visibleMapRect);
if (MKMapRectIsNull(intersection)) {
rect = MKMapRectUnion(rect, _mapView.visibleMapRect);
region = MKCoordinateRegionForMapRect(rect);
_intermediateAnimation = YES;
}
[_mapView setRegion:region animated:YES];
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
if (_intermediateAnimation) {
_intermediateAnimation = NO;
[_mapView setRegion:_destinationRegion animated:YES];
}
}
这个辅助方法取自这里
MKMapRect MKMapRectForCoordinateRegion(MKCoordinateRegion region)
{
MKMapPoint a = MKMapPointForCoordinate(CLLocationCoordinate2DMake(
region.center.latitude + region.span.latitudeDelta / 2,
region.center.longitude - region.span.longitudeDelta / 2));
MKMapPoint b = MKMapPointForCoordinate(CLLocationCoordinate2DMake(
region.center.latitude - region.span.latitudeDelta / 2,
region.center.longitude + region.span.longitudeDelta / 2));
return MKMapRectMake(MIN(a.x,b.x), MIN(a.y,b.y), ABS(a.x-b.x), ABS(a.y-b.y));
}
WWDC 2013 session 309 Putting Map Kit in Perspective解释了如何在 iOS 7 中进行如此复杂的转换。