2009-07-27 21 views
9

Un AnnotationView personalizado se actualiza con nuevas coordenadas. Pero el problema es que se actualiza visualmente solo después de algunas manipulaciones con MKMapView, p. acercar o mover. ¿Qué debo hacer para actualizar manualmente la posición visual en un mapa?MKMapView refresh after pin moves

PS. Intenté cambiar la región por la región del mapa actual. Pero sí cambia el zoom. Es extraño.

[mapView setRegion:[mapView region] animated:YES]; 
+0

Sírvase ver mi respuesta en el siguiente enlace: http://stackoverflow.com/a/24564868/665961 –

Respuesta

19

Estoy un poco chiflado después de horas de investigación. La respuesta es simple:

[mapView setCenterCoordinate:mapView.region.center animated:NO]; 

No me pregunte por qué, pero actualiza una vista de mapa y es lo que necesitaba.

+1

UPD: no ayuda con SDK 3.1. Todavía en investigación. – slatvick

+1

tampoco funciona en 3.1.2. – bradheintz

+0

¡Esto acaba de arreglar mi error! ¡¡¡¡¡Gracias!!!!! –

-7

Aquí es la interfaz para MapAnnotation:

// CSMapAnnotation.h 
// mapLines 
// Created by Craig on 5/15/09. 
// Copyright 2009 Craig Spitzkoff. All rights reserved. 

#import <Foundation/Foundation.h> 
#import <MapKit/MapKit.h>  

// types of annotations for which we will provide annotation views. 
typedef enum { 
    MapAnnotationTypeStart = 0, 
    MapAnnotationTypeEnd = 1, 
    MapAnnotationTypeImage = 2 
} MapAnnotationType; 

@interface MapAnnotation : NSObject <MKAnnotation> 
{ 
    CLLocationCoordinate2D _coordinate; 
    MapAnnotationType  _annotationType; 
    NSString*    _title; 
    NSString*    _subtitle; 
    NSString*    _userData; 
    NSString*    speed; 
    NSString*    identifier; 
} 

@property (nonatomic, retain) NSString *speed; 
@property (nonatomic, retain) NSString *identifier; 

-(id) initWithCoordinate:(CLLocationCoordinate2D)coordinate 
    annotationType: (MapAnnotationType) annotationType 
    title: (NSString*) title 
    subtitle: (NSString*) subtitle 
    speed: (NSString *) speed 
    identifier: (NSString *) identifier;  
-(id) setWithCoordinate: (CLLocationCoordinate2D) coordinate 
    annotationType: (MapAnnotationType) annotationType 
    title: (NSString*) title 
    subtitle: (NSString*) subtitle 
    speed: (NSString*) speed 
    identifier: (NSString*) identifier;  
@property MapAnnotationType annotationType; 
@property (nonatomic, retain) NSString* userData;  
@end  

Y aquí es la implementación:

// CSMapAnnotation.m 
// mapLines 
// Created by Craig on 5/15/09. 
// Copyright 2009 Craig Spitzkoff. All rights reserved. 

#import "MapAnnotation.h"  

@implementation MapAnnotation 

@synthesize coordinate  = _coordinate; 
@synthesize annotationType = _annotationType; 
@synthesize userData  = _userData; 
@synthesize speed; 
@synthesize identifier; 

-(id) initWithCoordinate:(CLLocationCoordinate2D)coordinate 
    annotationType: (MapAnnotationType) annotationType 
    title: (NSString*)title 
    subtitle: (NSString*) subtitle 
    speed: (NSString *) speedz 
    identifier: (NSString *) identifierz 
{ 
    self = [super init]; 
    _coordinate = coordinate; 
    _title = [title retain]; 
    _subtitle = [subtitle retain]; 
    _annotationType = annotationType; 
    speed = speedz; 
    identifier = identifierz; 
    return self; 
}  
-(id) setWithCoordinate:(CLLocationCoordinate2D)coordinate 
    annotationType: (MapAnnotationType) annotationType 
    title: (NSString*) title 
    subtitle: (NSString*) subtitle 
    speed: (NSString*) speedz 
    identifier: (NSString*) identifierz 
{ 
    _coordinate = coordinate; 
    _title = [title retain]; 
    _subtitle = [subtitle retain]; 
    _annotationType = annotationType; 
    speed = speedz; 
    identifier = identifierz;  
    return self; 
}  
-(NSString*) title 
{ 
    return _title; 
}  
-(NSString*) subtitle 
{ 
    return _subtitle; 
}  
-(void) dealloc 
{ 
    [_title release]; 
    [_userData release]; 
    [super dealloc]; 
}  
@end 
12

MKMapView observa la propiedad de las anotaciones de coordenadas a través de KVO. Simplemente necesita observar el protocolo adecuado KVO y enviar la anotación willChangeValueForKey: y didChangeValueForKey: con keypath de @"coordinate" antes y después de actualizar las coordenadas.

Del mismo modo title y subtitle también son observados por MKMapView. por lo que si se actualiza esos y desea que el valor de la llamada a cambiar de forma automática y sin ningún esfuerzo por su parte, acaba de hacer lo mismo: llaman willChangeValueForKey: y didChangeValueForKey:

+0

Eso es realmente bueno saber, gracias. – samvermette

+0

Mientras funciona 'setCenterCoordinate: animated:', la forma KVO aquí también funciona y es definitivamente más apropiada y permite que 'MKMapView' coordine mejor las actualizaciones de múltiples observaciones. –

-2

No hay razón para que no se puede quitar y volver a agregar la anotación . Probablemente sea mucho más eficiente que mover todo el mapa, incluso si es un movimiento falso.

+0

¿Alguien quiere explicar por qué esto fue votado negativamente? Esta es al menos una alternativa y yo diría que es más eficiente. –

+0

Estoy seguro de que la mayoría de las personas que encontraron este hilo ya lo habían intentado; Sé que lo hice. Esto causa un comportamiento extraño. –

2

¡La respuesta aquí NO es refrescar el MapView o la Anotación!

la propiedad de coordenadas de MKAnnotation tiene KVO en ella. Si simplemente agrega el puntero de identificación, el objeto que desea en el mapa, la vista de mapa y actualiza la propiedad de coordenadas con una nueva ubicación, MKMapView hará el resto por usted.

¡Lo más cerca posible de un almuerzo gratis!

9

si agrega las modificaciones de un hilo, no funcionará. tuve el mismo problema y simplemente envolviendo mi función que se agregó las anotaciones con la siguiente trabajaron

[self performSelectorOnMainThread:@selector(addCameraIconOnMain:) obj waitUntilDone:true]; 

-(void) addCameraIconOnMain:(myobjecttype*)obj 
{ 
    // this isnt the entire function, customize for your own purpose..... 
    [mapView addAnnotation:annotation]; 
} 
0

He resuelto este error con una llamada asincrónica, por lo menos 0,5 demora.

ej .: [self performSelector:@selector(redrawPins) withObject:nil afterDelay:0.5];

Donde "redrawPins" es la función que agrega y quita pasadores.