Как мне увеличить MKMapView до текущего местоположения пользователя без CLLocationManager? - PullRequest
70 голосов
/ 19 марта 2010

В MKMapView есть опция «Показать текущее местоположение пользователя», которая автоматически отображает местоположение пользователя на map.

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

Проблема в том, что при обновлении пользовательского местоположения на map, похоже, нет никакого метода, поэтому мне некуда поместить код, который будет zoom/scroll.

Есть ли способ получить уведомление, когда MKMapView получил (или обновил) местоположение пользователя, чтобы я мог перемещать / увеличивать его? Если я использую свои CLLocationManager, полученные мной обновления не соответствуют обновлениям маркера пользователя на карте, поэтому, когда моя карта перемещается, она выглядит глупо и увеличивает масштаб изображения за несколько секунд до появления синей булавки.

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

Ответы [ 6 ]

106 голосов
/ 05 апреля 2010

Вы должны зарегистрироваться для уведомлений KVO userLocation.location свойство MKMapView.

Для этого поместите этот код в viewDidLoad: вашего ViewController или в любое место в месте инициализации вида карты.

[self.mapView.userLocation addObserver:self  
        forKeyPath:@"location"  
           options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)  
           context:NULL];

Затем реализуйте этот метод для получения уведомлений KVO

- (void)observeValueForKeyPath:(NSString *)keyPath  
                      ofObject:(id)object  
                        change:(NSDictionary *)change  
                       context:(void *)context {  

    if ([self.mapView showsUserLocation]) {  
        [self moveOrZoomOrAnythingElse];
        // and of course you can use here old and new location values
    }
}

Этот код отлично работает для меня.
Кстати, self - мой ViewController в этом контексте.

52 голосов
/ 23 мая 2011

Это комбинация ответа ДДНВ и Дастина, который работал для меня:

mapView - это имя MKMapView * mapView;

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

- (void) viewDidLoad
{
    [self.mapView.userLocation addObserver:self 
                                forKeyPath:@"location" 
                                   options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
                                   context:nil];
}

Затем создайте метод фактического листинга, который перемещает карту в текущее местоположение:

// Listen to change in the userLocation
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{       
    MKCoordinateRegion region;
    region.center = self.mapView.userLocation.coordinate;  

    MKCoordinateSpan span; 
    span.latitudeDelta  = 1; // Change these values to change the zoom
    span.longitudeDelta = 1; 
    region.span = span;

    [self.mapView setRegion:region animated:YES];
}

Не забудьте правильно разложить делок и отменить регистрацию наблюдателя:

- (void)dealloc 
{
    [self.mapView.userLocation removeObserver:self forKeyPath:@"location"];
    [self.mapView removeFromSuperview]; // release crashes app
    self.mapView = nil;
    [super dealloc];
}
45 голосов
/ 28 марта 2012

Начиная с iOS 5.0 Apple добавила новый метод в MKMapView.Этот метод делает именно то, что вы хотите, и даже больше.

Взгляните на: https://developer.apple.com/documentation/mapkit/mkmapview

- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated;
13 голосов
/ 04 ноября 2011

Вы можете отслеживать, когда MKMapView обновляет местоположение пользователя на карте, применяя протокол MKMapViewDelegate. Просто внедрите:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation      {
    CLLocationAccuracy accuracy = userLocation.location.horizontalAccuracy;
    if (accuracy ......) {
    } 
}

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

6 голосов
/ 22 апреля 2014

Попробуйте это:

[mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
1 голос
/ 19 марта 2010

Нет проблем ... Внутри метода viewDidLoad вашего подкласса UIViewController, имеющего MKMapView, добавьте это (при условии, что ваш MKMapView назван map):

CLLocation *location = [[[CLLocation alloc] initWithLatitude:map.centerCoordinate.latitude longitude:map.centerCoordinate.longitude] autorelease]; //Get your location and create a CLLocation
MKCoordinateRegion region; //create a region.  No this is not a pointer
region.center = location.coordinate;  // set the region center to your current location
MKCoordinateSpan span; // create a range of your view
span.latitudeDelta = BASE_RADIUS / 3;  // span dimensions.  I have BASE_RADIUS defined as 0.0144927536 which is equivalent to 1 mile
span.longitudeDelta = BASE_RADIUS / 3;  // span dimensions
region.span = span; // Set the region's span to the new span.
[map setRegion:region animated:YES]; // to set the map to the newly created region
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...