Как я могу динамически установить диапазон MKMapView, чтобы он не «привязывался» к начальному региону при перерисовке карты? - PullRequest
1 голос
/ 28 июня 2011

Я работаю с MKMapview, и у меня возникла проблема с уровнем масштабирования и диапазоном региона.

Может показаться, что при обновлении MKMapView регион сбрасывается в значения, которые были жестко закодированы, когдаЯ изначально их установил.Я отслеживаю местоположение пользователя и при любых изменениях в местоположении телефона карта должна обновляться через CLLocationManagerDelegate и метод делегата, перечисленные ниже.

В настоящее время у меня есть это в locationManager: didUpdateToLocation: fromLocation:

    MKCoordinateSpan span;
    span.latitudeDelta =  0.8;  
    span.longitudeDelta = 0.8;     
    MKCoordinateRegion region;
    region.center = newLocation.coordinate;
    region.span = span;
    [self.MyMapView setRegion:region animated:NO];

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

-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated

. Я мог бы полностью обойти эту проблему, но я не точно уверен, как мне это сделать.

В конечном счете, я бы хотел, чтобы карта перестала «привязываться» к вышеуказанному промежутку.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 28 марта 2012

Мне удалось решить эту проблему, создав подкласс UIViewController для хранения экземпляра MKMapView. Я восстановил диапазон mapView в loadView, а затем вызвал [mapView setUserTrackingMode:...] в методе viewWillAppear VC.

Я видел поведение OP, описанное в предыдущей реализации, где я на лету создал VC и экземпляр MKMapView, а затем вставил его в мой контроллер навигации. Мне никогда не удавалось ни установить диапазон, ни настроить отслеживание пользователей, чтобы они следовали за пользователем без потери интервала. Я выполнил некоторую отладку и даже увидел, что исходные значения диапазона были отброшены при отображении представления, поэтому я думаю, что это как-то связано с настройкой диапазона или режима отслеживания пользователя без отображения представления. В любом случае, организация кода, описанного выше, решила проблему.

Вот соответствующие биты:

// ===== mainVC.h =====
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
@interface MapVC : UIViewController <MKMapViewDelegate>
@end

// ===== mainVC.m =====   
static MapVC *map = nil;

- (void)mapAction {
    UINavigationController *nav = [self navigationController];

    // map VC is a singleton
    if (!map) map = [[MapVC alloc] init];

    [nav pushViewController:map animated:TRUE];
}


// ===== MapVC.m =====
- (void)loadView {
    mapView = [[MKMapView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [mapView setDelegate:self];
    MKCoordinateSpan span = MKCoordinatSpanMake(storedLatitudeDelta, storedLongitudeDelta);
    [mapView setRegion:MKCoordinateRegionMake(storedCenter, span)];
    [self setView:mapView];
}

- (void)viewWillAppear:(BOOL)animated {
    [mapView setUserTrackingMode:MKUserTrackingModeFollow animated:TRUE];
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    MKCoordinateSpan mySpan = [mapView region].span;
    storedLatitudeDelta = mySpan.latitudeDelta;
    storedLongitudeDelta = mySpan.longitudeDelta;
}

Я сократил это из более крупного проекта, поэтому дайте мне знать, если вы видите какие-либо опечатки, но в этом суть.

0 голосов
/ 29 июня 2011

Если вы пытаетесь сохранить карту в центре текущего местоположения пользователя, сначала решите, хотите ли вы использовать:

  • свойство userLocation представления карты и метод делегата представления карты mapView:didUpdateUserLocation:, или
  • CLLocationManager и его метод делегата locationManager:didUpdateToLocation:fromLocation:

С любым из них, в viewDidLoad, вы должны просто установить начальную область просмотра карты, включая центр(используя некоторую координату по умолчанию) и span.Местоположение пользователя вряд ли будет доступно сразу в viewDidLoad, так как получение может занять несколько секунд.

Попытка использовать userLocation до его установки может вызвать исключение при настройке региона с этим значением.

Если используется вид карты 101 userLocation, то:

  • в viewDidLoad или IB, установите mapView.showsUserLocation на YES
  • в методе mapView:didUpdateUserLocation:, сделайте mapView.centerCoordinate = userLocation.location.coordinate; (или используйте setCenterCoordinate:animated:)
  • , рекомендуйте также реализовать mapView:didFailToLocateUserWithError: для обработки или, по крайней мере, получения информации о сбоях

Если используется CLLocationManager, то:

  • в viewDidLoad, выполните [locationManager startUpdatingLocation];
  • в методе locationManager:didUpdateToLocation:fromLocation: выполните mapView.centerCoordinate = newLocation.coordinate; (или используйте анимированный метод)
  • рекомендуйте также реализовать locationManager:didFailWithError: для обработки или, по крайней мере, осознания сбоев
...