放大MKMapView以适应注释引脚?

我正在使用MKMapView,并在大约5-10公里区域的地图上添加了许多注释引脚。当我运行应用程序时,我的地图开始缩小以显示整个世界,缩放地图以使大头针适合视图的最佳方法是什么?

<强>编辑: 我最初的想法是使用MKCoordinateRegionMake并从我的注释中计算坐标中心,longitudeDelta和latitudeDelta。我很确定这将工作,但我只是想检查我没有错过任何明显的东西

代码添加,BTW: FGLocation是一个符合MKAnnotation的类,locationFake是这些对象的NSMutableArray。欢迎评论....

- (MKCoordinateRegion)regionFromLocations {
CLLocationCoordinate2D upper = [[locationFake objectAtIndex:0] coordinate];
CLLocationCoordinate2D lower = [[locationFake objectAtIndex:0] coordinate];


// FIND LIMITS
for(FGLocation *eachLocation in locationFake) {
if([eachLocation coordinate].latitude > upper.latitude) upper.latitude = [eachLocation coordinate].latitude;
if([eachLocation coordinate].latitude < lower.latitude) lower.latitude = [eachLocation coordinate].latitude;
if([eachLocation coordinate].longitude > upper.longitude) upper.longitude = [eachLocation coordinate].longitude;
if([eachLocation coordinate].longitude < lower.longitude) lower.longitude = [eachLocation coordinate].longitude;
}


// FIND REGION
MKCoordinateSpan locationSpan;
locationSpan.latitudeDelta = upper.latitude - lower.latitude;
locationSpan.longitudeDelta = upper.longitude - lower.longitude;
CLLocationCoordinate2D locationCenter;
locationCenter.latitude = (upper.latitude + lower.latitude) / 2;
locationCenter.longitude = (upper.longitude + lower.longitude) / 2;


MKCoordinateRegion region = MKCoordinateRegionMake(locationCenter, locationSpan);
return region;
}
107899 次浏览

你说对了。

找到你的最大和最小纬度和经度,应用一些简单的算术,并使用MKCoordinateRegionMake

对于iOS 7及以上版本,使用showAnnotations:animated:,来自MKMapView.h:

// Position the map such that the provided array of annotations are all visible to the fullest extent possible.
- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated NS_AVAILABLE(10_9, 7_0);

这是我找到的在这里,为我工作:

(编辑:我已经更新了解决方案,使用@Micah的建议增加pointRect 0.1,以确保rect最终不会无穷小!)

MKMapRect zoomRect = MKMapRectNull;
for (id <MKAnnotation> annotation in mapView.annotations)
{
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
[mapView setVisibleMapRect:zoomRect animated:YES];

,

你也可以通过替换第一行来更新包含userLocation引脚:

MKMapPoint annotationPoint = MKMapPointForCoordinate(mapView.userLocation.coordinate);
MKMapRect zoomRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);

@jowie的解决方案很棒。有一个问题,如果一个地图只有一个注释,你最终会得到一个完全缩小的地图。我给矩形的make size增加了0.1,以确保setVisibleMapRect有可以缩放的东西。

MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);

在for循环中添加这个If循环,以从该方法中排除用户的位置引脚(在我的情况中需要,也可能是其他情况)

if (![annotation isKindOfClass:[MKUserLocation class]] ) {


//Code Here...


}

在你的代码中添加如下内容:

  - (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
id<MKAnnotation> mp = [annotationView annotation];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate] ,250,250);


[mv setRegion:region animated:YES];


}

我使用这段代码,对我来说很好:

-(void)zoomToFitMapAnnotations:(MKMapView*)aMapView
{
if([aMapView.annotations count] == 0)
return;


CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;


CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;


for(MapViewAnnotation *annotation in mapView.annotations)
{
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);


bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
}


MKCoordinateRegion region;
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides


region = [aMapView regionThatFits:region];
[mapView setRegion:region animated:YES];
}

我对MKMapView Category的拉斐尔的代码做了一点修改。

- (void)zoomToFitMapAnnotations {
if ([self.annotations count] == 0)
return;


CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;


CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;


for (id <MKAnnotation> annotation in self.annotations) {
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);


bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
}


MKCoordinateRegion region;
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides


[self setRegion:[self regionThatFits:region] animated:YES];
}

本页所有的答案假设地图占据了整个屏幕。我实际上有一个HUD显示器(即按钮分散在顶部和底部),在地图的顶部提供信息。因此,页面上的算法将显示引脚,但其中一些将出现 HUD显示按钮。

我的解决方案将地图放大到屏幕的在子集中显示注释,并适用于不同的屏幕尺寸(即3.5“vs 4.0”等):

// create a UIView placeholder and throw it on top of the original mapview
// position the UIView to fit the maximum area not hidden by the HUD display buttons
// add an *other* mapview in that uiview,
// get the MKCoordinateRegion that fits the pins from that fake mapview
// kill the fake mapview and set the region of the original map
// to that MKCoordinateRegion.

下面是我在代码中所做的(注意:我使用NSConstraints和一些帮助器方法来使我的代码在不同的屏幕尺寸下工作。虽然代码是相当可读的..我的答案在这里解释得更好。这基本上是相同的工作流程:)

// position smallerMap to fit available space
// don't store this map, it will slow down things if we keep it hidden or even in memory
[@[_smallerMapPlaceholder] mapObjectsApplyingBlock:^(UIView *view) {
[view removeFromSuperview];
[view setTranslatesAutoresizingMaskIntoConstraints:NO];
[view setHidden:NO];
[self.view addSubview:view];
}];


NSDictionary *buttonBindingDict = @{ @"mapPlaceholder": _smallerMapPlaceholder};


NSArray *constraints = [@[@"V:|-225-[mapPlaceholder(>=50)]-176-|",
@"|-40-[mapPlaceholder(<=240)]-40-|"
] mapObjectsUsingBlock:^id(NSString *formatString, NSUInteger idx){
return [NSLayoutConstraint constraintsWithVisualFormat:formatString options:0 metrics:nil views:buttonBindingDict];
}];


[self.view addConstraints:[constraints flattenArray]];
[self.view layoutIfNeeded];


MKMapView *smallerMap = [[MKMapView alloc] initWithFrame:self.smallerMapPlaceholder.frame];
[_smallerMapPlaceholder addSubview:smallerMap];


MKCoordinateRegion regionThatFits = [smallerMap getRegionThatFits:self.mapView.annotations];
[smallerMap removeFromSuperview];
smallerMap = nil;
[_smallerMapPlaceholder setHidden:YES];


[self.mapView setRegion:regionThatFits animated:YES];

下面是获取合适区域的代码:

- (MKCoordinateRegion)getRegionThatFits:(NSArray *)routes {
MKCoordinateRegion region;
CLLocationDegrees maxLat = -90.0;
CLLocationDegrees maxLon = -180.0;
CLLocationDegrees minLat = 90.0;
CLLocationDegrees minLon = 180.0;
for(int idx = 0; idx < routes.count; idx++)
{
CLLocation* currentLocation = [routes objectAtIndex:idx];
if(currentLocation.coordinate.latitude > maxLat)
maxLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.latitude < minLat)
minLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.longitude > maxLon)
maxLon = currentLocation.coordinate.longitude;
if(currentLocation.coordinate.longitude < minLon)
minLon = currentLocation.coordinate.longitude;
}
region.center.latitude     = (maxLat + minLat) / 2.0;
region.center.longitude    = (maxLon + minLon) / 2.0;
region.span.latitudeDelta = 0.01;
region.span.longitudeDelta = 0.01;


region.span.latitudeDelta  = ((maxLat - minLat)<0.0)?100.0:(maxLat - minLat);
region.span.longitudeDelta = ((maxLon - minLon)<0.0)?100.0:(maxLon - minLon);


MKCoordinateRegion regionThatFits = [self regionThatFits:region];
return regionThatFits;
}

多亏了jowie,我更新了我的旧类别到更优雅的解决方案。共享完成,几乎复制粘贴就绪的解决方案

MKMapView + AnnotationsRegion.h

#import <MapKit/MapKit.h>


@interface MKMapView (AnnotationsRegion)


-(void)updateRegionForCurrentAnnotationsAnimated:(BOOL)animated;
-(void)updateRegionForCurrentAnnotationsAnimated:(BOOL)animated edgePadding:(UIEdgeInsets)edgePadding;


-(void)updateRegionForAnnotations:(NSArray *)annotations animated:(BOOL)animated;
-(void)updateRegionForAnnotations:(NSArray *)annotations animated:(BOOL)animated edgePadding:(UIEdgeInsets)edgePadding;


@end

MKMapView + AnnotationsRegion.m

#import "MKMapView+AnnotationsRegion.h"


@implementation MKMapView (AnnotationsRegion)


-(void)updateRegionForCurrentAnnotationsAnimated:(BOOL)animated{
[self updateRegionForCurrentAnnotationsAnimated:animated edgePadding:UIEdgeInsetsZero];
}
-(void)updateRegionForCurrentAnnotationsAnimated:(BOOL)animated edgePadding:(UIEdgeInsets)edgePadding{
[self updateRegionForAnnotations:self.annotations animated:animated edgePadding:edgePadding];
}


-(void)updateRegionForAnnotations:(NSArray *)annotations animated:(BOOL)animated{
[self updateRegionForAnnotations:annotations animated:animated edgePadding:UIEdgeInsetsZero];
}
-(void)updateRegionForAnnotations:(NSArray *)annotations animated:(BOOL)animated edgePadding:(UIEdgeInsets)edgePadding{
MKMapRect zoomRect = MKMapRectNull;
for(id<MKAnnotation> annotation in annotations){
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
[self setVisibleMapRect:zoomRect edgePadding:edgePadding animated:animated];
}


@end

希望它能帮助到一些人,再次感谢jowie!

苹果为IOS 7添加了一种新方法来简化生活。

[mapView showAnnotations:yourAnnotationArray animated:YES];

你可以很容易地从存储在地图视图中的数组中提取:

yourAnnotationArray = mapView.annotations;

快调整相机!

mapView.camera.altitude *= 1.4;

除非用户安装了iOS 7+或OS X 10.9+,否则这将不起作用。检查自定义动画在这里

 - (void)zoomMapViewToFitAnnotationsWithExtraZoomToAdjust:(double)extraZoom
{


if ([self.annotations count] == 0) return;


int i = 0;
MKMapPoint points[[self.annotations count]];


for (id<MKAnnotation> annotation in [self annotations])
{
points[i++] = MKMapPointForCoordinate(annotation.coordinate);
}


MKPolygon *poly = [MKPolygon polygonWithPoints:points count:i];


MKCoordinateRegion r = MKCoordinateRegionForMapRect([poly boundingMapRect]);
r.span.latitudeDelta += extraZoom;
r.span.longitudeDelta += extraZoom;


[self setRegion: r animated:YES];


}

@“我不确定这是否是因为我的实现中的一些其他因素,但我发现showannotation并不像手动实现那样接近缩放/适合注释,所以我坚持使用手动实现。——Ted Avery 4月17日0:35

我也有同样的问题,但后来我试着做了两次showannotation(如下所示),出于某种原因,它工作了。

[mapView showAnnotations:yourAnnotationArray animated:YES]; [mapView showAnnotations:yourAnnotationArray animated:YES]

正如Abhishek Bedi在一篇评论中指出的那样,对于iOS7,最好的方法是:

//from API docs:
//- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated NS_AVAILABLE(10_9, 7_0);
[self.mapView showAnnotations:self.mapView.annotations animated:YES];

对于我的个人项目(在iOS7之前),我只是在MKMapView类上添加了一个类别来封装“可见区域”功能,用于一个非常常见的操作:将其设置为能够看到MKMapView实例上当前加载的所有注释(这包括您可能放置的尽可能多的引脚,以及用户的位置)。结果是:

. h文件

#import <MapKit/MapKit.h>


@interface MKMapView (Extensions)


-(void)ij_setVisibleRectToFitAllLoadedAnnotationsAnimated:(BOOL)animated;
-(void)ij_setVisibleRectToFitAnnotations:(NSArray *)annotations animated:(BOOL)animated;




@end

m文件

#import "MKMapView+Extensions.h"


@implementation MKMapView (Extensions)


/**
*  Changes the currently visible portion of the map to a region that best fits all the currently loadded annotations on the map, and it optionally animates the change.
*
*  @param animated is the change should be perfomed with an animation.
*/
-(void)ij_setVisibleRectToFitAllLoadedAnnotationsAnimated:(BOOL)animated
{
MKMapView * mapView = self;


NSArray * annotations = mapView.annotations;


[self ij_setVisibleRectToFitAnnotations:annotations animated:animated];


}




/**
*  Changes the currently visible portion of the map to a region that best fits the provided annotations array, and it optionally animates the change.
All elements from the array must conform to the <MKAnnotation> protocol in order to fetch the coordinates to compute the visible region of the map.
*
*  @param annotations an array of elements conforming to the <MKAnnotation> protocol, holding the locations for which the visible portion of the map will be set.
*  @param animated    wether or not the change should be perfomed with an animation.
*/
-(void)ij_setVisibleRectToFitAnnotations:(NSArray *)annotations animated:(BOOL)animated
{
MKMapView * mapView = self;


MKMapRect r = MKMapRectNull;
for (id<MKAnnotation> a in annotations) {
ZAssert([a conformsToProtocol:@protocol(MKAnnotation)], @"ERROR: All elements of the array MUST conform to the MKAnnotation protocol. Element (%@) did not fulfill this requirement", a);
MKMapPoint p = MKMapPointForCoordinate(a.coordinate);
//MKMapRectUnion performs the union between 2 rects, returning a bigger rect containing both (or just one if the other is null). here we do it for rects without a size (points)
r = MKMapRectUnion(r, MKMapRectMake(p.x, p.y, 0, 0));
}


[mapView setVisibleMapRect:r animated:animated];


}


@end
如您所见,到目前为止,我已经添加了2个方法:一个用于将映射的可见区域设置为适合MKMapView实例上当前加载的所有注释的区域,另一个方法用于将其设置为任何对象数组。 因此,要设置mapView的可见区域,代码将像

一样简单
   //the mapView instance
[self.mapView ij_setVisibleRectToFitAllLoadedAnnotationsAnimated:animated];

我希望这对你有所帮助=)

对于iOS 7及以上版本(参考MKMapView.h):

// Position the map such that the provided array of annotations are all visible to the fullest extent possible.


- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated NS_AVAILABLE(10_9, 7_0);

来自- Abhishek Bedi的评论

你只需呼叫:

 [yourMapView showAnnotations:@[yourAnnotation] animated:YES];

以下是我的看法:

如果你在storyboard中使用xCode > 6与“推断”屏幕大小(参见文件检查器上的“模拟指标”),调用

- (void)showAnnotations:(NSArray *)注释 动画(BOOL):动画< /代码> < / p >

viewDidLoad中将导致iphone上的缩放级别太大(4英寸),因为地图的布局仍然是在故事板中更宽屏幕的大小上。

你可以把调用从showAnnotations...移到viewDidAppear。然后地图的大小已经调整到iPhone 4的小屏幕。

或者将文件检查器中“模拟指标”下的“推断”值更改为iphone 4英寸。

我已经转换了Rafael Moreira的答案。功劳归于他。 对于那些正在寻找Swift版本的人,下面是代码:

 func zoomToFitMapAnnotations(aMapView: MKMapView) {
guard aMapView.annotations.count > 0 else {
return
}
var topLeftCoord: CLLocationCoordinate2D = CLLocationCoordinate2D()
topLeftCoord.latitude = -90
topLeftCoord.longitude = 180
var bottomRightCoord: CLLocationCoordinate2D = CLLocationCoordinate2D()
bottomRightCoord.latitude = 90
bottomRightCoord.longitude = -180
for annotation: MKAnnotation in myMap.annotations as! [MKAnnotation]{
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude)
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude)
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude)
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude)
}


var region: MKCoordinateRegion = MKCoordinateRegion()
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.4
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.4
region = aMapView.regionThatFits(region)
myMap.setRegion(region, animated: true)
}

如果你正在寻找iOS 8及以上版本,最简单的方法是在调用func showAnnotations(annotations: [MKAnnotation], animated: Bool)之前设置地图视图的var layoutMargins: UIEdgeInsets { get set }

例如(Swift 2.1):

@IBOutlet weak var map: MKMapView! {
didSet {
map.delegate = self
map.mapType = .Standard
map.pitchEnabled = false
map.rotateEnabled = false
map.scrollEnabled = true
map.zoomEnabled = true
}
}


// call 'updateView()' when viewWillAppear or whenever you set the map annotations
func updateView() {
map.layoutMargins = UIEdgeInsets(top: 25, left: 25, bottom: 25, right: 25)
map.showAnnotations(map.annotations, animated: true)
}

与iOS 7兼容的方法是使用以下方法。首先调用showAnnotation以获得一个包含所有注释的矩形。然后创建和UIEdgeInset,并在顶部插入引脚高度。这样就可以确保在地图上显示整个大头针。

[self.mapView showAnnotations:self.mapView.annotations animated:YES];
MKMapRect rect = [self.mapView visibleMapRect];
UIEdgeInsets insets = UIEdgeInsetsMake(pinHeight, 0, 0, 0);
[self.mapView setVisibleMapRect:rect edgePadding:insets animated:YES];

基于上面的答案,你可以使用通用方法缩放地图,以适应所有的注释和叠加在同一时间。

-(MKMapRect)getZoomingRectOnMap:(MKMapView*)map toFitAllOverlays:(BOOL)overlays andAnnotations:(BOOL)annotations includeUserLocation:(BOOL)userLocation {
if (!map) {
return MKMapRectNull;
}


NSMutableArray* overlaysAndAnnotationsCoordinateArray = [[NSMutableArray alloc]init];
if (overlays) {
for (id <MKOverlay> overlay in map.overlays) {
MKMapPoint overlayPoint = MKMapPointForCoordinate(overlay.coordinate);
NSArray* coordinate = @[[NSNumber numberWithDouble:overlayPoint.x], [NSNumber numberWithDouble:overlayPoint.y]];
[overlaysAndAnnotationsCoordinateArray addObject:coordinate];
}
}


if (annotations) {
for (id <MKAnnotation> annotation in map.annotations) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
NSArray* coordinate = @[[NSNumber numberWithDouble:annotationPoint.x], [NSNumber numberWithDouble:annotationPoint.y]];
[overlaysAndAnnotationsCoordinateArray addObject:coordinate];
}
}


MKMapRect zoomRect = MKMapRectNull;
if (userLocation) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(map.userLocation.coordinate);
zoomRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
}


for (NSArray* coordinate in overlaysAndAnnotationsCoordinateArray) {
MKMapRect pointRect = MKMapRectMake([coordinate[0] doubleValue], [coordinate[1] doubleValue], 0.1, 0.1);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}


return zoomRect;
}

然后:

MKMapRect mapRect = [self getZoomingRectOnMap:mapView toFitAllOverlays:YES andAnnotations:YES includeUserLocation:NO];
[mapView setVisibleMapRect:mapRect edgePadding:UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0) animated:YES];

迅速使用

mapView.showAnnotations(annotationArray, animated: true)

Objective c中

[mapView showAnnotations:annotationArray animated:YES];
    var zoomRect: MKMapRect = MKMapRect.null
for annotation in mapView.annotations {
let annotationPoint = MKMapPoint(annotation.coordinate)
let pointRect = MKMapRect(x: annotationPoint.x, y: annotationPoint.y, width: 0.1, height: 0.1)
zoomRect = zoomRect.union(pointRect)
}
mapView.setVisibleMapRect(zoomRect, animated: true)

//编辑为swift 5

在斯威夫特

    var zoomRect = MKMapRectNull;


for i in 0..<self.map.annotations.count {


let annotation: MKAnnotation = self.map.annotations[i]


let annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
let pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}


self.map.setVisibleMapRect(zoomRect, animated: true)

我创建了一个扩展来显示所有的注释使用一些代码从这里和那里在swift。这将不会显示所有注释,如果他们不能显示,即使在最大缩放级别。

import MapKit


extension MKMapView {
func fitAllAnnotations() {
var zoomRect = MKMapRectNull;
for annotation in annotations {
let annotationPoint = MKMapPointForCoordinate(annotation.coordinate)
let pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50), animated: true)
}
}

这是适合地图中所有注释的正确方法。

func zoomMapaFitAnnotations() {


var zoomRect = MKMapRectNull
for annotation in mapview.annotations {


let annotationPoint = MKMapPointForCoordinate(annotation.coordinate)


let pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0)


if (MKMapRectIsNull(zoomRect)) {
zoomRect = pointRect
} else {
zoomRect = MKMapRectUnion(zoomRect, pointRect)
}
}
self.mapview.setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsetsMake(50, 50, 50, 50), animated: true)


}

您可以选择要在标注中显示的形状。

extension MKMapView {
func setVisibleMapRectToFitAllAnnotations(animated: Bool = true,
shouldIncludeUserAccuracyRange: Bool = true,
shouldIncludeOverlays: Bool = true,
edgePadding: UIEdgeInsets = UIEdgeInsets(top: 35, left: 35, bottom: 35, right: 35)) {
var mapOverlays = overlays


if shouldIncludeUserAccuracyRange, let userLocation = userLocation.location {
let userAccuracyRangeCircle = MKCircle(center: userLocation.coordinate, radius: userLocation.horizontalAccuracy)
mapOverlays.append(MKOverlayRenderer(overlay: userAccuracyRangeCircle).overlay)
}


if shouldIncludeOverlays {
let annotations = self.annotations.filter { !($0 is MKUserLocation) }
annotations.forEach { annotation in
let cirlce = MKCircle(center: annotation.coordinate, radius: 1)
mapOverlays.append(cirlce)
}
}


let zoomRect = MKMapRect(bounding: mapOverlays)
setVisibleMapRect(zoomRect, edgePadding: edgePadding, animated: animated)
}
}


extension MKMapRect {
init(bounding overlays: [MKOverlay]) {
self = .null
overlays.forEach { overlay in
let rect: MKMapRect = overlay.boundingMapRect
self = self.union(rect)
}
}
}

2021年推出Swift 5+

// Position the map such that the provided array of annotations are all visible to the fullest extent possible.
@available(iOS 7.0, *)
open func showAnnotations(_ annotations: [MKAnnotation], animated: Bool)

所以你可以:

 mapView.showAnnotations(mapView.annotations, animated: true)