Поместите это в свой код соответственно:

ользую MKMapView и добавил несколько булавок для аннотаций на карту около 5-10 километров. Когда я запускаю приложение, моя карта начинает уменьшаться, чтобы показать весь мир, каков наилучший способ увеличить карту так, чтобы контакты соответствовали виду?

РЕДАКТИРОВАТЬ: Сначала я хотел бы использовать MKCoordinateRegionMake и рассчитать центр координат, longitudeDelta и latitudeDelta из моих аннотаций. Я уверен, что это сработает, но я просто хотел проверить, не упустил ли я ничего очевидного.

Код добавлен, кстати: 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;
}
 user46710516 окт. 2013 г., 03:12
примечание iOS 7: новыйshowAnnotations: анимированные: Метод может помочь вам избежать этого ручного расчета региона.

Ответы на вопрос(24)

чтобы немного упростить жизнь.

[mapView showAnnotations:yourAnnotationArray animated:YES];

Вы можете легко извлечь из массива, сохраненного в виде карты:

yourAnnotationArray = mapView.annotations;

и быстро настроить камеру тоже!

mapView.camera.altitude *= 1.4;

это не будет работать, если у пользователя не установлена ​​iOS 7+ или OS X 10.9+. проверить пользовательскую анимациюВот

 Ted Avery17 апр. 2014 г., 02:35
Я не уверен, если это из-за некоторых других факторов в моей реализации, но я считаю, чтоshowAnnotations не делает так близкого масштабирования / подгонки аннотаций, как ручная реализация, поэтому я остановился на ручной.
 Ryan Berg30 мая 2014 г., 04:47
попробуйте умножить высоту камеры на единицу, например mapView.camera.altitude * = .85; для более близкого видового экрана
 MandisaW07 мар. 2016 г., 18:32
Я также нашел это полезным для выбора аннотаций вне текущей видимой области карты. По умолчанию MapView не выбирает невидимые аннотации. Вызовите showAnnotations с массивом ваших невидимых аннотаций перед вызовом selectAnnotation, и карта должна обновить свою видимую область.

ас, кто ищет версию 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)
}

Я сделал небольшую модификациюРафаэля код для категории MKMapView.

- (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];
}

Если вы используете xCode> 6 с «выведенными» размерами для экранов (см. «Имитированные метрики» в Инспекторе файлов) в раскадровке, вызывая

- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated

вviewDidLoad приведет к слишком большому уровню масштабирования на iPhone с 4 дюймами, поскольку макет карты по-прежнему соответствует размеру более широких экранов раскадровки.

Вы можете переместить ваш звонок наshowAnnotations... вviewDidAppear, Тогда размер карты уже настроен на меньший экран iPhone 4.

Или же измените значение «выведено» в инспекторе файлов в разделе «смоделированные метрики» на 4-дюймовый iphone.

предположим, что карта занимает весь экран, У меня на самом деле есть дисплей HUD (то есть кнопки, разбросанные сверху и снизу), которые дают информацию поверх карты ... и поэтому алгоритмы на странице будут правильно отображать контакты, но некоторые из них появятсяпод кнопки дисплея HUD.

Мое решение увеличивает масштаб карты доотображать аннотации в подмножестве экрана и работает дляразные размеры экрана (т.е. 3.5 "против 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;
}

чтобы показать все аннотации с использованием некоторого кода здесь и там в быстром. Это не покажет все аннотации, если они не могут быть показаны даже при максимальном уровне масштабирования.

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: UIEdgeInsetsMake(20, 20, 20, 20), animated: true)
    }
}
 nyxee07 июн. 2017 г., 12:03
Мне удалось получить лучшие результаты, изменивUIEdgeInsetsMake параметры, значения между 30 и 100 были хороши для меня. Я тестировал с помощью iPhone SE i) S 10.2 Simulator. Пример кода:setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsetsMake(100, 100, 100, 100), animated: true), Как примечание, этот код работает в Swift 3 и XCode 8.2.1.
    var zoomRect: MKMapRect = MKMapRectNull
    for annotation in mapView.annotations {
        let annotationPoint = MKMapPointForCoordinate(annotation.coordinate)
        let pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1)
        zoomRect = MKMapRectUnion(zoomRect, pointRect)
    }
    mapView.setVisibleMapRect(zoomRect, animated: true)

вы можете использовать универсальный метод для масштабирования карты, чтобы соответствовать всем аннотациям и наложениям одновременно.

-(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];

В Свифте

    
    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)

шения. Совместное использование готового решения для копирования и вставки

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

Надеюсь, это поможет кому-то и еще раз спасибо, Джоуи!

Swift 3 Это правильный способ размещения всех аннотаций на карте.

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)

    }

-(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];
}
 Olexiy Pyvovarov30 янв. 2019 г., 21:01
Не работают для: elements 2 элементов ▿ 0: CLLocationCoordinate2D - широта: 46.969995730376894 - долгота: -109.2494943434474 ▿ 1: CLLocationCoordinate2D - широта: 63.23212154333072 - долгота: 174.13666611126533

Вот это сработало для меня:

(РЕДАКТИРОВАТЬ: я обновил решение, используя предложение @ Мики, чтобы увеличить pointRect на 0,1, чтобы убедиться, что прямоугольник не будет бесконечно малым!)

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);
 Craig B05 авг. 2013 г., 02:03
Очень хорошее решение !!! Вот еще один небольшой штрих для добавления отступов: double inset = -zoomRect.size.width * 0.1; [self.mapView setVisibleMapRect: MKMapRectInset (zoomRect, inset, inset) animated: YES];
 Farhad Malekpour01 февр. 2015 г., 01:24
Решение @CraigB для заполнения отлично, но оно не работает хорошо, когда путь вертикальный, например, с юга на север, чтобы исправить это, используйте двойную вставку = MIN (-zoomRect.size.width * 0.1, -zoomRect.size. высота * 0,1);
 shannoga27 нояб. 2011 г., 15:11
+1 что сказал @martin
 FelixLam24 янв. 2013 г., 17:41
Действительно хорошо. Вам не нужно проверять isNull, хотя. MKMapRectUnion делает это для вас. Из документов: «Если один из прямоугольников равен нулю, этот метод возвращает другой прямоугольник».
 dulgan06 мар. 2015 г., 11:59
Улучшение с отступом: double insetWidth = -zoomRect.size.width * 0.2; double insetHeight = -zoomRect.size.height * 0.2; MKMapRect insetRect = MKMapRectInset (zoomRect, insetWidth, insetHeight); Тогда используйте этот новый insertRect
Решение Вопроса

Найдите свои максимальные и минимальные широты и долготы, примените простую арифметику и используйте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);
 Gordon Dove23 сент. 2016 г., 13:21
Также стоит отметить, что хотя showAnnotations устанавливает область для отображения аннотаций, область по-прежнему настраивается в соответствии с соотношением сторон; и это часто исключает некоторые аннотации. Также обратите внимание, что showAnnotations - единственное правильное решение, представленное здесь; ни один из других ответов даже не пытается обработать аннотации, охватывающие международную линию дат.
 Abhishek Bedi30 янв. 2014 г., 21:01
Для 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);
 RPM10 июл. 2015 г., 21:20
Это работает хорошо, но иногда, когда я увеличиваю масштаб (на карте), а затем пытаюсь отцентрировать его (используя кнопку, вызывающую этот метод), кажется, что он не работает.
 Eneko Alonso29 февр. 2016 г., 23:26
Важно отметить, чтоshowAnnotations также добавляет аннотации к карте, даже если аннотация для этого местоположения уже существует.
 alain.s18 авг. 2016 г., 21:46
@EnekoAlonso Вы можете обойти это, позвонивremoveAnnotations(_ annotations:) незамедлительно послеshowAnnotations(_ annotations:animated)

// 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);

замечание от - Абхишек Беди

Вы просто позвоните:

 [yourMapView showAnnotations:@[yourAnnotation] animated:YES];
 Matthew Frederick04 окт. 2017 г., 21:14
Просто для справки, текст NS_AVAILABLE был там, потому что в январе 2011 года наличие iOS 7 на устройстве было маловероятным, а NS_AVAILABLE защищало приложение от сбоя или сбоя сборки.

iOS 8 и выше, самый простой способ сделать это, чтобы установитьvar layoutMargins: UIEdgeInsets { get set } вашей карты перед вызовомfunc showAnnotations(annotations: [MKAnnotation], animated: Bool)

Например (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)
}

если на карте только одна аннотация, вы получите полностью уменьшенную карту. Я добавил 0.1 к размеру прямоугольника, чтобы убедиться, что setVisibleMapRect может что-то увеличить.

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

для iOS7 forward лучший способ сделать это:

//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]; 

Надеюсь, это поможет =)

Поместите это в свой код соответственно:

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

       [mv setRegion:region animated:YES];

}

чтобы исключить вывод местоположения пользователя из этого метода (требуется в моем случае и, возможно, других)

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

//Code Here...

}
 - (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 чтобы получить прямоугольник, включающий все аннотации. Затем создайте и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];

@ "Я не уверен, что это из-за некоторых других факторов в моей реализации, но я обнаружил, что showAnnotations не делает такое же близкое масштабирование / подгонку аннотаций, как ручная реализация, поэтому я застрял с ручной.

У меня была такая же проблема, но затем я попытался сделать showAnnotations дважды (как показано ниже), и по какой-то причине это сработало.

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

В Swift используют

mapView.showAnnotations(annotationArray, animated: true)

В объективе c

[mapView showAnnotations:annotationArray animated:YES];
 Justin Vallely06 нояб. 2018 г., 16:17
Если аннотации уже были установлены в mapView, вы можете ссылаться на них напрямую с помощью:mapView.showAnnotations(mapView.annotations, animated: true)

Ваш ответ на вопрос