我有MKMapView
annotation pins
。加载视图时,将搜索最近的引脚,并且地图将进行缩放,以便显示用户的位置和最近的引脚。我用[map setRegion:region animated:YES];
做到了。到目前为止一切正常。也可以通过点击定位用户的按钮来调用相同的方法,然后完成我刚才描述的操作。
我还有一个搜索字段,用户可以使用该搜索字段搜索地图点。当用户点击其中一个搜索结果时,地图会设置该区域,以便搜索到的图钉位于中间。 现在,有一些奇怪的东西。我也设置了这个区域的动画,至少我做了与上面相同的命令。但是,如果地图点距离地图的当前可见部分太远,则在更改区域时不会显示动画。 我错过了什么吗?我已经看过苹果文档了,他们没有提到有关动画最大距离的任何内容。
我期待着任何帮助!
更新1:
刚在模拟器中再次测试它。一个有趣的事实是,当我第一次搜索 MapPoint 然后选择搜索结果时,它没有动画。如果我在第一个之后执行另一个搜索并选择一个结果,它会进行动画处理。一旦我点击了将用户带回到他的位置的最近点的定位按钮,它就不会为此setRegion:
设置动画,并在此之后进行第一次搜索。但只有在模拟器中,在我的4S上,它完全按照我在上面的原始问题中描述的那样。
更新2:
在评论中,我被要求提供示例坐标
所以这里是第一步的坐标(搜索自己的位置和最近的引脚):
我的位置: 47.227131 / 8.264251
最近的针脚: 47.251347 / 8.357191
它们之间的距离约为22公里。地图的中心是两个引脚之间的中心。从中心到屏幕边界的距离是两点之间距离的1.5倍,这意味着在这种情况下约为33公里
这里是第二步的一组坐标(搜索地图点并选择它):
搜索引脚:46.790680 / 9.818824
屏幕边框的距离固定为500米。
答案 0 :(得分:13)
我已经在iOS 6和iOS 7 beta上使用简单的演示应用程序测试了这个问题。事实证明,地图视图实际上并不总是为区域之间的过渡设置动画。这取决于地区分开的距离。例如,从巴黎到伦敦的过渡不是动画。但是,如果你先缩小一点,然后去伦敦就会动画。
文档说:
动画:如果您希望地图视图为其设置动画,请指定YES 如果您希望地图居中,请转换到新地区或否 立即指定区域。
但正如我们所见,我们不能依赖动画。我们只能告诉地图视图,应过渡动画。 MapKit决定动画是否合适。它告诉代表是否将在-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
中动画转换。
为了在所有情况下始终为区域变化设置动画,您需要先设置中间区域的动画。设A为当前地图区域,B为目标区域。如果区域之间存在交叉,则可以直接转换。 (将MKCoordinateRegion
转换为MKMapRect
并使用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];
}
}
此辅助方法取自here
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会议309 将Map Kit放入透视解释了如何在iOS 7中进行此类复杂转换。
答案 1 :(得分:1)
以下是@Felix重写为Swift 4的函数:
// MARK: - MapView help properties
var destinationRegion: MKCoordinateRegion?
var intermediateAnimation = false
func center() {
// Center map
var initialCoordinates = CLLocationCoordinate2D(latitude: 49.195061, longitude: 16.606836)
var regionRadius: CLLocationDistance = 5000000
destinationRegion = MKCoordinateRegionMakeWithDistance(initialCoordinates, regionRadius * 2.0, regionRadius * 2.0)
centreMap(on: destinationRegion!)
}
private func mapRect(forCoordinateRegion region: MKCoordinateRegion) -> MKMapRect {
let topLeft = CLLocationCoordinate2D(latitude: region.center.latitude + (region.span.latitudeDelta/2), longitude: region.center.longitude - (region.span.longitudeDelta/2))
let bottomRight = CLLocationCoordinate2D(latitude: region.center.latitude - (region.span.latitudeDelta/2), longitude: region.center.longitude + (region.span.longitudeDelta/2))
let a = MKMapPointForCoordinate(topLeft)
let b = MKMapPointForCoordinate(bottomRight)
return MKMapRect(origin: MKMapPoint(x:min(a.x,b.x), y:min(a.y,b.y)), size: MKMapSize(width: abs(a.x-b.x), height: abs(a.y-b.y)))
}
func centreMap(on region: MKCoordinateRegion) {
var region = region
var rect = mapRect(forCoordinateRegion: region)
let intersection = MKMapRectIntersection(rect, mapView.visibleMapRect)
if MKMapRectIsNull(intersection) {
rect = MKMapRectUnion(rect, mapView.visibleMapRect)
region = MKCoordinateRegionForMapRect(rect)
intermediateAnimation = true
}
mapView.setRegion(region, animated: true)
}
// MARK: - MKMapViewDelegate
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
if intermediateAnimation, let region = destinationRegion {
intermediateAnimation = false
mapView.setRegion(region, animated: true)
}
}
答案 2 :(得分:1)
我也有这个问题,它不会总是动画,有时它只会跳跃和溶解。但是,我注意到如果您为相机而不是区域设置动画,它会一直动画。
但是使用相机时,您必须设置眼距/高度而不是纬度/经度。我有一个简单的计算,下面是粗略的,它基本上只是将高度(以米为单位)设置为与该区域的经度跨度相同的米数。如果你想要精确的准确度,你必须计算出该区域纬度的每度数米数,这个数字会略有变化,因为地球不是一个完美的球体。当然,您可以将该值乘以扩大或缩小视图以进行品味。
Swift 4.1 示例代码:
/* -------------------------------------------------------------------------- */
func animateToMapRegion(_ region: MKCoordinateRegion) {
// Quick and dirty calculation of altitude necessary to show region.
// 111 kilometers per degree longitude.
let metersPerDegree: Double = 111 * 1_000
let altitude = region.span.longitudeDelta * metersPerDegree
let camera = MKMapCamera(lookingAtCenter: region.center, fromEyeCoordinate: region.center, eyeAltitude: altitude)
self.mapView.setCamera(camera, animated: true)
}
答案 3 :(得分:1)
您只需获取您的当前位置,然后调用此函数:
◙ f = []
a = []
for i in range(10):
a.append(i)
f.append(list(a)) #amended line
a.clear()
>>>print(f)
[[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]]
◙ import MapKit
◙ var appleMapView = MKMapView()
currentCoordinate必须是您当前的位置坐标:
var currentCoordinate: CLLocationCoordinate2D?
答案 4 :(得分:0)
对于拥有相同问题且正在使用Swift且正在使用tableView的任何人:
我在解除tableView后调用了setRegion,它没有显示动画。这是我编辑之前的代码:
dismiss(animated: true, completion: nil)
a function that calls setRegion
然后我把它改为:
dismiss(animated: true, completion: {
a function that calls setRegion
})
这次它有效。