iphone - ¿Cómo acerco un MKMapView a la ubicación actual de los usuarios sin CLLocationManager?
(6)
Debe registrarse para las notificaciones de userLocation.location
propiedad MKMapView
de MKMapView
.
Para hacer esto, coloque este código en viewDidLoad:
de su ViewController o en cualquier lugar del lugar donde se inicializa su vista de mapa.
[self.mapView.userLocation addObserver:self
forKeyPath:@"location"
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
context:NULL];
A continuación, implemente este método para recibir notificaciones de 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
}
}
Este código funciona bien para mí.
Por cierto, self
soy mi ViewController en este contexto.
Con MKMapView
hay una opción llamada "Mostrar la ubicación actual de los usuarios" que mostrará automáticamente la ubicación de los usuarios en el map
.
Me gustaría moverme y acercarme a esta ubicación cuando se encuentre (y si cambia).
El problema es que no parece haber ningún método llamado cuando la ubicación del usuario se actualiza en el map
, por lo que no tengo dónde colocar el código que se zoom/scroll
.
¿Hay alguna manera de recibir notificaciones cuando MKMapView
tiene (o actualiza) la ubicación del usuario para poder moverlo / acercarme a él? Si utilizo mi propio CLLocationManager
las actualizaciones que recibo no se corresponden con las actualizaciones del marcador de usuario en el mapa, por lo que parece tonto cuando mi mapa se mueve y hace zoom unos segundos antes de que aparezca el pin azul.
Esto parece una funcionalidad básica, pero he pasado semanas buscando una solución y no encontré nada cerca.
Desde iOS 5.0, Apple ha agregado un nuevo método a MKMapView. Este método hace exactamente lo que quiere y más.
Eche un vistazo a: https://developer.apple.com/documentation/mapkit/mkmapview
- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated;
Esta es una combinación de ddnv y la respuesta de Dustin que funcionó para mí:
mapView es el nombre de MKMapView * mapView;
En viewDidLoad agregue esta línea, tenga en cuenta que podría haber más líneas en la carga. Esto simplemente se simplifica.
- (void) viewDidLoad
{
[self.mapView.userLocation addObserver:self
forKeyPath:@"location"
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
context:nil];
}
Luego, crea el método de listado real que mueve el mapa a la ubicación actual:
// 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];
}
No olvide desasignar correctamente y anular el registro del observador:
- (void)dealloc
{
[self.mapView.userLocation removeObserver:self forKeyPath:@"location"];
[self.mapView removeFromSuperview]; // release crashes app
self.mapView = nil;
[super dealloc];
}
No hay problema ... Dentro del método viewDidLoad de su subclase UIViewController que tiene MKMapView agregue esto (suponiendo que su MKMapView se llame 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
Prueba esto:
[mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
Puede supervisar cuándo MKMapView
actualiza la ubicación del usuario en el mapa mediante la implementación del protocolo MKMapViewDelegate
. Solo implemente:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
CLLocationAccuracy accuracy = userLocation.location.horizontalAccuracy;
if (accuracy ......) {
}
}
Esta devolución de llamada debe estar perfectamente sincronizada con lo que se muestra en el mapa.