Масштабирование MKMapView для подгонки аннотаций?
Я использую MKMapView и добавил несколько примечаний на карту около 5-10 километров. Когда я запускаю приложение, моя карта начинает уменьшаться, чтобы показать весь мир, каков наилучший способ масштабирования карты, чтобы контакты соответствовали виду?
EDIT:
Мое первоначальное мышление состояло в том, чтобы использовать 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;
}
Ответы
Ответ 1
У тебя все в порядке.
Найдите максимальные и минимальные широты и долготы, примените простую арифметику и используйте 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);
Ответ 2
Вот что я нашел здесь, который работал у меня:
(EDIT: я обновил решение, используя предложение @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);
Ответ 3
Apple добавила новый метод для IOS 7, чтобы немного упростить жизнь.
[mapView showAnnotations:yourAnnotationArray animated:YES];
Вы можете легко извлечь из массива, сохраненного в виде карты:
yourAnnotationArray = mapView.annotations;
и быстро отрегулируйте камеру!
mapView.camera.altitude *= 1.4;
это не сработает, если у пользователя не установлена iOS 7+ или OS X 10.9+. проверить пользовательскую анимацию здесь
Ответ 4
Я использую этот код и отлично работаю для меня:
-(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];
}
Ответ 5
В Swift используйте
mapView.showAnnotations(annotationArray, animated: true)
В Objective c
[mapView showAnnotations:annotationArray animated:YES];
Ответ 6
Решение @jowie отлично работает. Один улов, если на карте есть только одна аннотация, вы получите полностью увеличенную карту. Я добавил 0,1 к размеру прямоугольника, чтобы убедиться, что setVisibleMapRect имеет что-то, чтобы увеличить.
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
Ответ 7
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)
}
Ответ 8
Я обратился к Рафаэлю Морейре. Кредит принадлежит ему.
Для тех из вас, кто ищет версию 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)
}
Ответ 9
Если вы ищете 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)
}
Ответ 10
Я создал расширение, чтобы показать все аннотации с использованием некоторого кода здесь и там в быстром. Это не покажет все аннотации, если они не могут быть показаны даже при максимальном уровне масштабирования.
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)
}
}
Ответ 11
Добавлен этот цикл If в цикле for, чтобы исключить контакт местоположения пользователей из этого метода (требуется в моем случае и, возможно, другие)
if (![annotation isKindOfClass:[MKUserLocation class]] ) {
//Code Here...
}
Ответ 12
Для 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);
замечание - Абхишек Беди
Вы просто вызываете:
[yourMapView showAnnotations:@[yourAnnotation] animated:YES];
Ответ 13
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
Ответ 14
В Swift
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)
Ответ 15
Благодаря 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!
Ответ 16
- (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];
}
Ответ 17
Как говорит Абхишек Беди в комментарии, для 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 file
#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];
Я надеюсь, что это поможет =)
Ответ 18
Все ответы на этой странице предполагают, что карта занимает весь экран. У меня на самом деле есть 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;
}
Ответ 19
Я немного изменил код Rafael для категории 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];
}
Ответ 20
Основываясь на ответах выше, вы можете использовать универсальный метод для масштабирования карты, чтобы одновременно соответствовать всем аннотациям и оверлеям.
-(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];
Ответ 21
Просто поделитесь своими наблюдениями по этому поводу:
Если вы используете xCode > 6 с "выводимыми" размерами для экранов (см. "имитированные показатели" в инспекторе файлов) в раскадровке, вызывая
- (void)showAnnotations:(NSArray *)annotations
animated:(BOOL)animated
в viewDidLoad
приведет к слишком большому уровню масштабирования на iPhone с 4 дюймами, потому что макет карты по-прежнему находится на размер более широких экранов из раскадровки.
Вы можете перевести свой вызов на showAnnotations...
на viewDidAppear
. Затем размер карты уже настроен на меньший экран iPhone 4.
Или, альтернативно, измените значение "inferred" в инспекторе файлов в разделе "Моделируемые показатели" на iphone 4 дюйма.
Ответ 22
Другой способ в Swft 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)
}
Ответ 23
Вставьте это в свой код соответственно:
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
id<MKAnnotation> mp = [annotationView annotation];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate] ,250,250);
[mv setRegion:region animated:YES];
}
Ответ 24
@ "Я не уверен, что это связано с некоторыми другими факторами в моей реализации, но я обнаружил, что showAnnotations не делает так близко приближение/привязку аннотаций, как это делает ручная реализация, поэтому я застрял с ручным. - Ted Avery Apr 17 at 0:35"
У меня была та же проблема, но затем я попытался сделать showAnnotations дважды (например, ниже), и по какой-то причине он сработал.
[mapView showAnnotations: yourAnnotationArray animated: YES];
[mapView showAnnotations: yourAnnotationArray animated: YES];
Ответ 25
Совместимый с 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];