С помощью MKMapView
появится опция "Показать текущее местоположение пользователей", которая автоматически покажет местоположение пользователя на map
.
Я бы хотел переместить и увеличить масштаб до этого местоположения, когда оно будет найдено (и если оно изменится).
Проблема заключается в том, что не появляется какой-либо метод, называемый при обновлении местоположения пользователя на map
, поэтому мне некуда поставить код, который будет zoom/scroll
.
Есть ли способ получить уведомление, когда MKMapView
получил (или обновил) местоположение пользователя, чтобы я мог перемещать/масштабировать его? Если я использую свой собственный CLLocationManager
, то обновляемые обновления не соответствуют обновлениям маркера пользователя на карте, поэтому он выглядит глупым, когда моя карта перемещается и масштабирует секунды до появления синего штыря.
Это похоже на базовую функциональность, но я потратил несколько недель на поиски решения и ничего не закрыл.
Ответ 1
Вам необходимо зарегистрироваться для уведомлений 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
}
}
Этот код отлично подходит для меня.
BTW, self
- это мой ViewController в этом контексте.
Ответ 2
Это комбинация ответов ddnv и Dustin, которые работали для меня:
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];
}
Ответ 3
Так как iOS 5.0 Apple добавила новый метод в MKMapView. Этот метод делает именно то, что вы хотите, и многое другое.
Взгляните на: https://developer.apple.com/documentation/mapkit/mkmapview
- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated;
Ответ 4
Вы можете отслеживать, когда MKMapView
обновляет местоположение пользователя на карте, реализуя протокол MKMapViewDelegate
. Просто выполните:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
CLLocationAccuracy accuracy = userLocation.location.horizontalAccuracy;
if (accuracy ......) {
}
}
Этот обратный вызов должен быть полностью синхронизирован с тем, что отображается на карте.
Ответ 5
Попробуйте следующее:
[mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
Ответ 6
Нет проблем... Внутри метода viewDidLoad вашего подкласса UIViewController, который имеет MKMapView, добавьте это (если ваш MKMapView называется картой):
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 span to the new span.
[map setRegion:region animated:YES]; // to set the map to the newly created region