¿Es posible mover las coordenadas de un MKAnnotation sin añadir y eliminar la anotación del mapa?
Cómo mover una MKAnnotation sin añadir / quitar desde el mapa?
He encontrado un método bastante simple. Quería actualizar la posición de mi reproductor sin problemas sin necesidad de retirar y volver a añadir el reproductor de anotación. Esto funciona bien para los pre-iOS4 aplicaciones, y lo que hace es a la vez mover el pasador y centrar el mapa en la nueva ubicación del pin:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
[UIView commitAnimations];
Aquí es lo mismo, pero con la característica de bloque recomendado para iOS4:
[UIView animateWithDuration:0.5 animations:^{
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
}];
De hecho, es posible sin eliminar y añadir la anotación fuera de curso.
Tendrá que observar a su MKAnnotation de coordinar y actualizar la posición de la MKAnnotationView cuando cambia. Alternativamente, usted puede (y esto es probablemente la forma más elegante de hacerlo) derivar su propio MKAnnotation y MKAnnotationView y hacerlos "móvil".
Ver Moving-MKAnnotationView para un ejemplo detallado que también anima la posición de la anotación.
Subclase MKPointAnnotation y tiene la capacidad de actualizar la vista de anotación en el mapa a la nueva coordenada de forma automática.
Sólo tiene que utilizar MVA:
[annotation willChangeValueForKey:@"coordinate"];
[annotation didChangeValueForKey:@"coordinate"];
Si su MKAnnotation tiene un método setCoordinate, basta con incluir estas líneas justo ahí:
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
[self willChangeValueForKey:@"coordinate"];
coordinate = newCoordinate;
[self didChangeValueForKey:@"coordinate"];
}
No sé si se trata de manera más general posible, pero es que si usted tiene su propio MKAnnotationView personalizado.
Yo era capaz de adaptar el enfoque documentado en http://spitzkoff.com/craig/?p=108 por Craig Spitzkoff:
- Dar a su costumbre MKAnnotationView una referencia a su objeto MKAnnotation
- Añadir un método updateCoordinates al objeto MKAnnotation y llamarlo cuando se desea cambiar la ubicación de la anotación
- Llamar RegionChanged en el MKAnnotationView encargo para hacerle saber cuándo debe reposicionarse (por ejemplo, cuando MKAnnotation ha actualizado coordenadas)
- En drawRect en la vista de objetos internos propiedad de su encargo MKAnnotationView puede reposicionar usando las coordenadas de la MKAnnotation (que está sosteniendo una referencia a él).
Es probable que podría simplificar aún más este enfoque - puede que no requiere un objeto de vista interno en todas las circunstancias.
Después de actualizar las coordenadas o algunas otras propiedades de la anotación, simplemente llame siguiente método MKMapViewDelegate para volver a trazar su anotación:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
p.ej:
myAnnotation.coordinate = CLLocationCoordinate2DMake([newLat doubleValue], [newLon doubleValue]);
[self mapView:self.mapView viewForAnnotation:myAnnotation];
La mayoría de las respuestas se basan en el hecho de que la anotación se ha realizado a través de extender MKPlacemark. Pero ¿qué pasa con (es decir, la imagen personalizada para el marcador) cualquier otro objeto que sólo implementa el protocolo MKAnnotation? No tendría el método setCoordinate. Así que aquí está la respuesta basada en el código, proporcionada por 100 gramos
MKAnnotationView *av = [self.mapView viewForAnnotation:user];
//user is an object which implements <MKAnnotation>
// You will probably get your MKAnnotationView in your own way
if (av){
// here user returns CLLocationCoordinate2D coordinate
MKMapPoint mapPoint = MKMapPointForCoordinate([user getLastLocation]);
// converting mapPoint to CGPoint
CGPoint newPos;
CGFloat zoomFactor = self.mapView.visibleMapRect.size.width / self.mapView.bounds.size.width;
newPos.x = mapPoint.x/zoomFactor;
newPos.y = mapPoint.y/zoomFactor;
// animation for annotation's move
static NSString *POSITION_KEY=@"positionAnimation";
static NSString *PATH_ANIMATION_KEY=@"position";
if (MKMapRectContainsPoint(self.mapView.visibleMapRect, mapPoint)) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:PATH_ANIMATION_KEY];
animation.fromValue = [NSValue valueWithCGPoint:av.center];
animation.toValue = [NSValue valueWithCGPoint:newPos];
animation.duration = 0.3;
animation.delegate = av;
animation.fillMode = kCAFillModeForwards;
[av.layer addAnimation:animation forKey:POSITION_KEY];
}
// moving view
av.center = newPos;
por lo que básicamente necesita para obtener el correspondiente MKAnnotationView que podría ser también logró por iteración a través de todas las anotaciones y la nueva ubicación. Hice un soporte de matriz para todos de la misma (NSMutableArray * mapAnnotaions) por lo que ahora podría iterar al igual que:
for (id annotation in mapAnnotaions) {call refresh method here for id}
Si se mantiene una referencia a su anotación, realizar un cambio en la propiedad de coordenadas, a continuación, añadir la anotación al mapa nuevo, la ubicación de la vista de anotación se actualizará. No es necesario para eliminar la anotación (lo que hará que la vista de anotación a desaparecer momentáneamente). Esto no le dará una buena transición para coordinar cuando se actualiza sin embargo, la anotación. También no se traduce en una pérdida de memoria ni hay un múltiplo de la misma anotación añadido al mapa (si nos fijamos en el número de anotaciones en el MapView, que se mantiene constante cuando se vuelve a añadir la anotación).
En Swift 4.0 y 11.0 del IOS, acabo de añadir atributo dinámico a la propiedad de coordenadas de clase hija de la clase MKAnnotation y funciona: Todas las anotaciones en MapView actualizar su ubicación si la coordenada valor de los objetos MKAnnotation se actualiza:
class CarAnnotation: NSObject, MKAnnotation {
@objc dynamic var coordinate: CLLocationCoordinate2D
//Add your custom code here
}
Echar un vistazo a mi MapKitDragAndDrop muestra, que le permite actualizar MKAnnotation y mover MKAnnotationView en el iPhone OS 3 y el IOS 4 (utilizará el soporte incorporado arrastrando).
No parece posible cambiar las coordenadas de un objeto MKAnnotation y luego informar al MKMapView del cambio.
Sin embargo, la eliminación de la anotación previa del mapa, el cambio de la coordenada de su objeto de anotación y añadiendo de nuevo al mapa funciona bien.
[theMapView removeAnnotation:myAnnotation];
[myAnnotation setLatitude:newLatitude];
[theMapView addAnnotation:myAnnotation];
¿Por qué no quiere hacerlo de esta manera?













