Pregunta ¿Cómo mover una MKAnnotación sin agregarla / quitarla del mapa?


¿Es posible mover la coordenada de una MKAnotación sin agregar y eliminar la anotación del mapa?


32
2018-02-13 01:44


origen


Respuestas:


Encontré un método bastante simple. Quería actualizar la posición de mi jugador sin problemas sin quitar y luego volver a agregar la anotación del jugador. Esto funciona bien para las aplicaciones anteriores a iOS4, y lo que hace es mover el pin 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];

Esto es lo mismo, pero con la función de bloque recomendada para iOS4:

[UIView animateWithDuration:0.5 animations:^{
    [player setCoordinate:aLoc.coordinate];
    [mapView setCenterCoordinate:aLoc.coordinate animated:NO];
}];

16
2017-07-05 13:47



De hecho es posible sin eliminar y agregar la anotación fuera de curso.

Deberá observar las coordenadas de su MKAnnotation y actualizar la posición de MKAnnotationView cuando cambie. Alternativamente, puede (y esta es probablemente la manera más elegante de hacerlo) derivar su propia MKAnnotation y MKAnnotationView y hacer que sean "movibles".

Ver Moving-MKAnnotationView para un ejemplo detallado que también anima la posición de la anotación.


6
2018-03-14 15:19



Solo usa KVO:

[annotation willChangeValueForKey:@"coordinate"];
[annotation didChangeValueForKey:@"coordinate"];

Si su MKAnnotation tiene un método setCoordinate, solo incluya estas líneas allí:

- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
    [self willChangeValueForKey:@"coordinate"];
    coordinate = newCoordinate;
    [self didChangeValueForKey:@"coordinate"];
}

4
2018-03-13 18:30



Subclase MKPointAnnotation y tiene la capacidad de actualizar automáticamente la vista de anotación en el mapa a la nueva coordenada.


4
2018-04-26 19:17



En Swift 4.0 e IOS 11.0, simplemente agrego el atributo dinámico a la propiedad de coordenadas de la clase hija de la clase MKAnnotation y funciona: Todas las anotaciones en MapView actualizan su ubicación si se actualiza el valor de coordenadas de los objetos MKAnnotation:

class CarAnnotation: NSObject, MKAnnotation {
    @objc dynamic var coordinate: CLLocationCoordinate2D
    //Add your custom code here
}

3
2018-03-15 09:30



No sé si es más generalmente posible, pero lo es si tiene su propio MKAnnotationView personalizado.

Pude adaptar el enfoque documentado en http://spitzkoff.com/craig/?p=108 por Craig Spitzkoff:

  1. Dale a tu MKAnnotationView personalizada una referencia a tu objeto MKAnnotation
  2. Agregar un método updateCoordinates al objeto MKAnnotation y llame cuando quieres cambiar la ubicación de la anotación
  3. Call regionChanged on the custom MKAnnotationView para avisar cuando para reposicionarse (por ejemplo, cuando MKAnnotation se ha actualizado coordenadas)
  4. En drawRect en el objeto de vista interna propiedad de su MKAnnotationView personalizado puede reposicionar usando las coordenadas de la MKAnnotación (estás sosteniendo una referencia a esto).

Es probable que pueda simplificar aún más este enfoque; es posible que no requiera un objeto de vista interno en todas las circunstancias.


2
2018-02-15 03:45



Si mantiene una referencia a su anotación, realice un cambio en la propiedad de coordenadas, luego agregue la anotación al mapa nuevamente, la ubicación de la vista de anotación se actualizará. No es necesario que elimine la anotación (lo que provocará que la vista de anotación desaparezca momentáneamente). Sin embargo, esto no le dará una buena transición para cuando se actualice la coordenada de anotación. Tampoco da como resultado una pérdida de memoria ni hay un múltiplo de la misma anotación agregada al mapa (si observa el número de anotaciones en la vista de mapa, permanece constante cuando vuelve a agregar la anotación).


1
2018-02-16 13:58



La mayoría de las respuestas se basan en el hecho de que su Anotación se ha realizado a través de MKPlacemark que se extiende. Pero, ¿qué pasa con cualquier otro objeto (es decir, una imagen personalizada para marcador) que solo implemente el protocolo MKAnnotation? No tendría el método setCoordinate. Así que aquí está la respuesta basada en el código, proporcionada por 100grams

    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;

así que básicamente necesitas obtener el MKAnnotationView correspondiente que también se puede lograr mediante la iteración a través de todas las anotaciones y su nueva ubicación. Hice un conjunto de matrices para todo (NSMutableArray * mapAnnotaions) por lo que ahora podría repetir lo siguiente:

for (id annotation in mapAnnotaions) {call refresh method here for id}

1
2017-07-18 16:31