extension MKMapView {
func showAnnotationsWithPadding(_ annotations: [MKAnnotation], padding: UIEdgeInsets, animated: Bool) {
// get the current rect
let currentMapRect = self.visibleMapRect
// show the annotations without animation to get the desired map rect
self.showAnnotations(annotations, animated: false)
// this is the rect we want to show
let desiredMapRect = self.visibleMapRect
// go back to previous rect to move with animation if wanted
if animated {
self.visibleMapRect = currentMapRect
}
// now we can show the annotations with padding
self.setVisibleMapRect(desiredMapRect, edgePadding: padding, animated: animated)
}
}
//1: Show all annotation on the map view, but without animation
self.mapView.showAnnotations(self.mapView.annotations, animated: false)
//2: Get the current visible map rect
let currentMapRect = self.mapView.visibleMapRect
//3: Create the edges inset that you want the map view to show all annotation within
let padding = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)
//4: Set current map rect but with new padding, also set animation to true to see effect
self.mapView.setVisibleMapRect(currentMapRect, edgePadding: padding, animated: true)
8条答案
按热度按时间0x6upsns1#
设置Map区域,使所有注解都包含在
MKMapView
的某个部分中,可以通过三个步骤完成。输入是mapView
和annotationsFrame
。1.计算包含所有注解的
MKMapRect
mapRect
。1.从
mapView.bounds
和annotationsFrame
计算填充插入。1.在Map视图上调用
-setVisibleMapRect:edgePadding:animated:
。下面是一个测试的屏幕截图。红色覆盖显示
annotationsFrame
。这里是代码。注意:这是一个方法,可以简化将其添加到代码中的过程,并且它没有针对边缘情况进行测试,例如传入具有相同坐标的n个注解,或者注解相距太远以至于Map必须缩小太多,或者坐标跨越Map边缘+/-180度经度。
如果你想要一个完美的位置(谁不这样做),这里有三件事要考虑:
1.代码确保所有坐标都在
annotationsFrame
中,但注解本身可能在外部。为了防止这种情况,只需使用更多的填充。例如,如果注解为20 x20并以坐标为中心,则在所有边上使用10个以上的填充。1.在iOS 7下,Map没有缩放到完美的缩放比例,而是缩放到下一个瓷砖大小(2的幂)。因此,注解周围的空间将比所需的更多,正如屏幕截图所示。
1.在iOS 7上,Map视图不仅可以完美缩放,还可以自动关注状态栏。要使计算正确,您需要从iOS 7上的顶部填充中减去状态栏高度。
blpfk2vs2#
从iOS 7.0开始,这可以通过
showAnnotations
轻松实现。斯威夫特:
Objective-C:
上面的语句将调整Map视图的visible rect以显示所有注解。
llmtgqce3#
我改进了凯尔麦的答案(https://stackoverflow.com/a/50663064/14745547)
不同的是,凯尔的答案是不是动画从以前的位置。
要以动画方式移动,请执行以下操作:
dba5bblo4#
首先需要添加注解:(当然,这是在你已经有了一个注解列表之后)
迅捷4:
您可以使用currentView常量或直接将MKMapRect放置为:下面:(.visibleMapRect返回:
“Map视图当前显示的区域。”
gwbalxhn5#
我发现了一个更简单的方法,不用计算,让Map视图计算它,然后我们调整边缘。
lnlaulya6#
如果你准备近似计算,你可以用一些聪明的缩放来做。
你的目标区域是80高的Map视图是380。因此,您需要一个比计算的区域高4.75倍的区域,以适合您的注解。(以上0.25,以下3.5)。
首先,你需要得到一个区域(或mapret,无论你喜欢在哪里工作),并使其与你的目标可视区域相同的比例。这是因为一个非常宽和短的区域不会接触到可视区域的顶部和底部,因此将其高度相乘不会使其接触到Map视图的顶部和底部。所以如果
viewable_height/viewable_width > annotations_height/annotations_width
,你应该把annotations_height
设置为annotations_width * (viewable_height/viewable_width)
。这样,您就可以在注解框的北部添加25%,在南部添加350%。您可以通过将中心向南移动212.5%(当前高度)并将垂直跨度增加475%来完成此操作。
现在,所有这些都是一个近似值,因为世界是球体,我们不是在看平面投影(即。赤道附近的1度纬度小于两极附近的1度)。但是如果你想精确的话,你可以根据纬度等因素来调整数字。如果你只处理城市规模的注解,你可能会没事。
希望能帮上忙。
bq3bfh9z7#
如果你想在给定的rect中找到注解:
为了确保标注VIEWS在矩形中,获取标注的区域,然后遍历它们并获取每个视图的边界,看看边界是否适合Map的visibleRect,如果不适合,修改区域!
~~像这样:
vktxenjb8#
尝试从所有注解边中获取lan和lon的值(最大和最小)。
在开始时定义此值:
然后使用此函数计算跨度和区域:
并在viewDidLoad方法中使用它: