2009-09-17 11 views
19

Mi aplicación conoce la posición actual del usuario (CoreLocation.framework). Tan pronto como el usuario abre un nuevo MapView, su iPhone comienza a buscar nuevamente la posición actual. ¿Es posible omitir eso o cambiar la posición del primer usuario para mkMapView?¿Cómo inicializar MKMapView con una ubicación de usuario determinada?

Editar:

¿Es posible sobrescribir MKMapView y utilizar otro LocationManager?

Respuesta

42

Sí, es posible tener un objeto de administrador de ubicación por separado y asignar su valor a la vista de mapa (BTW, estoy usando '=' a continuación como prefijo de lista para evitar que el formateador de código SO borking).

= En su UIViewController mantiene dos propiedades separadas: una a MKMapView y una a CLLocationManager.

= Cree un archivo XIB con el MKMapView y cualquier otra ventana que desee. Conecte las salidas a las propiedades del controlador. Asegúrese de que MKMapView NO siga la ubicación del usuario.

= Haga que el UIViewController implemente el protocolo CLLocationManagerDelegate, especialmente el método locationManager:didUpdateToLocation:fromLocation: que se invocará siempre que haya un nuevo valor de ubicación disponible. Configuraremos el controlador como delegado para el administrador de ubicación.

= En el método loadView de viewController, cargue el NIB con el MKMapView en él. Para dar su opinión al usuario, puede colocar un control numérico UIActivityIndicatorView y configurarlo en startAnimating. Entonces se comienza con:

self.locationManager = [[CLLocationManager alloc] init]; 
self.locationManager.delegate = self; 
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer; 
self.locationManager.distanceFilter = 10; // or whatever 
[self.locationManager startUpdatingLocation]; 

= En locationManager:didUpdateToLocation:fromLocation: comprobación para ver si el evento fue actualizado desde la última N segundos.Luego dígale al administrador de la ubicación que deje de actualizar, que deje de animar, y obtenga los datos latitud/longitud y asígnelos a la vista del mapa junto con un intervalo y una región de visualización para que se amplíe y centre en el lugar correcto.

= Ahora esta es la parte complicada: el "throbber" de mármol azul es una característica de la ubicación del usuario de seguimiento de mapview. Tendrás que 'fingir' momentáneamente hasta que el real se active (o simplemente usar un marcador separado para la ubicación actual y mantener tu posición por ti mismo). Personalmente, me gustaría ir con el mármol azul con el que el usuario está familiarizado.

= Para que se muestre correctamente al inicio, deberá crear una MKAnnotationView personalizada con solo el gráfico de mármol azul agregado en la ubicación devuelta por el administrador de ubicación. Esto significa tomar una instantánea de un Mapview con la ubicación mostrada, luego photoshopping solo el mármol azul y usarlo como la imagen para una vista de anotación personalizada.

= Si desea que siga activamente el mapa, puede habilitar el seguimiento de la ubicación del usuario de la vista de mapa y cuando obtiene los datos reales, oculta el marcador previamente establecido y deja que la vista de mapa realice la actualización. La otra opción es permitir que el administrador de ubicación existente continúe recibiendo actualizaciones cada segundo o más y actualice usted mismo la posición de la anotación de mármol azul.

= Para permitir que la propia userLocation de MapView do la actualización añadir a viewDidLoad:

[self.map.userLocation addObserver:self 
forKeyPath:@"location" 
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
context:NULL]; 
self.map.showsUserLocation = YES; // starts updating user location 

= Implementar observeValueForKeyPath. Que se llama cuando el atributo location del MapView de userlocation tiene un valor:

-(void)observeValueForKeyPath:(NSString *)keyPath 
     ofObject:(id)object 
     change:(NSDictionary *)change 
     context:(void *)context 
{ 
    if ([self.map isUserLocationVisible]) { 
     [self.locationManager stopUpdatingLocation]; 
     self.ownBlueMarble.hidden = YES; 
    } 
    // The current location is in self.map.userLocation.coordinate 
} 

= Para evitar el retraso de calentamiento en la ubicación actual, mantener una referencia a la viewController que contiene el mapa y la gerente de locación por lo que no desaparece (es un poco de memoria pero si lo liberas tendrás que esperar otra vez hasta que MapView cargue las teselas y esté listo para funcionar).

= En viewWillLoad puede rellenar la última ubicación conocida en la anotación de marcación personalizable personalizada y mostrarla. Active/desactive el seguimiento de UserLocation y cuando reciba la notificación, funcionará el mismo truco hide-the-annotation-show-the-real-marble. El administrador de ubicación del mapa propio se activa y cuando tiene los datos, puede hacer que su marcador de anotación desaparezca.

= Es posible que desee poner en práctica el método de la viewController viewWillDisappear y desactivar manualmente userLocation de seguimiento en el MapView por lo que es desactivada por defecto la próxima vez que la vista se conecta. También querrá obtener el último userLocation conocido y guardarlo para el siguiente arranque. De esta forma, puede hacer todos los malabarismos con marcadores de posición en el método viewWillAppear y no tener que preocuparse por la interferencia de UserLocation hasta que esté listo para hacerlo.

Buena suerte.

+1

Gracias Ramin. Esta no es la solución esperada, sin embargo, creo que es la más cercana existente. – jantimon

+0

Sí, hubiera sido mucho más fácil si nos permitieran establecer userLocation en una vista de mapa a un valor inicial ... o mejor todavía permitir el uso de una instancia existente de CLLocationManager en lugar de crear la suya propia ... pero desafortunadamente no lo hacen t. – Ramin

27

En su controlador:

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    CLLocationCoordinate2D coord = {latitude: 37.423617, longitude: -122.220154}; 
    MKCoordinateSpan span = {latitudeDelta: 1, longitudeDelta: 1}; 
    MKCoordinateRegion region = {coord, span}; 
    [mapView setRegion:region]; 
} 

Cuando mapa aparece que va a estar centrada cerca de Palo Alto

+0

eso no es lo que necesito. Quiero cambiar la posición del indicador de posición azul ("ubicación actual"). – jantimon

+1

userLocation es propiedad de solo lectura, dudo que pueda hacer algo al respecto. La única forma legal sería deshabilitar el indicador azul que Apple proporciona y escribir el suyo propio, que es un tipo de inútil – zakovyrya

+1

Establecer una región de 500m x 500 m [mapView setRegion: MKCoordinateRegionMakeWithDistance (CLLocationCoordinate2DMake (54.233498f, 1.99375f), 500, 500) ]; –

0

Trate de establecer la propiedad showUserLocation a falsa en la inicialización y luego restaurar el region la vista del mapa previamente tenía (Obviamente tendrá que almacenar esto antes de que se destruya el mapa anterior).

¿Esto es lo que quería?

+0

no, no se trata de la región, sino del indicador de posición – jantimon

0

No necesita utilizar otro Administrador de ubicaciones, puede agregar los puntos que desee al mapa y actualizarlos a través de cualquier otra lógica que desee.

Digamos que tiene una conexión de enchufe a un automóvil de control remoto, y ese automóvil envía datos de socket que contienen información de geolocalización en la carga útil. Podría analizarlo y actualizar la ubicación de la miniatura en su mapa en tiempo real. La propiedad "userLocation" no es necesaria para eso, pero puede mostrarla si lo desea.

La ubicación del usuario es de solo lectura, puede usarla o no. Eso no significa que necesite otro administrador de ubicación para hacer cualquier cosa que necesite hacer. Parece que su aplicación realmente no necesita esa característica, pero podría estar malinterpretando su pregunta.

+0

El problema es que la posición del usuario no se muestra o se muestra mal durante los primeros 10 segundos en que se muestra una nueva MKMapView. Después de estos 10 segundos todo está bien. Sin embargo, como conozco la posición, me encantaría omitir esos 10 segundos. – jantimon

+1

tal vez viejo, pero si alguien lee esto, debe obtener la ubicación del usuario al iniciar la aplicación, que iniciará el GPS para localizar al usuario. De esta forma, cuando el usuario abre el mapa, él/ella ya se ha localizado. pS: es bastante normal durante 10 segundos, incluso la aplicación Google Maps tarda unos segundos después de activar la ubicación – renevdkooi

Cuestiones relacionadas