Как переместить MKAnnotation без добавления / удаления его с карты? - PullRequest
36 голосов
/ 13 февраля 2010

Можно ли переместить координату примечания MKA, не добавляя и не удаляя примечание с карты?

Ответы [ 11 ]

17 голосов
/ 05 июля 2010

Я нашел довольно простой метод. Я хотел плавно обновить позицию своего игрока, не удаляя, а затем снова добавляя аннотацию игрока. Это хорошо работает для приложений, предшествующих iOS4, и перемещает булавку и центрирует карту на новом месте булавки:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
[UIView commitAnimations];

Вот то же самое, но с использованием рекомендованной функции блокировки для iOS4:

[UIView animateWithDuration:0.5 animations:^{
    [player setCoordinate:aLoc.coordinate];
    [mapView setCenterCoordinate:aLoc.coordinate animated:NO];
}];
9 голосов
/ 15 марта 2018

В Swift 4.0 и IOS 11.0 я просто добавляю динамический атрибут в свойство координат дочернего класса класса MKAnnotation, и это работает: все аннотации в MapView обновляют свое местоположение, если обновлено значение координат объектов MKAnnotation:

class CarAnnotation: NSObject, MKAnnotation {
    @objc dynamic var coordinate: CLLocationCoordinate2D
    //Add your custom code here
}
7 голосов
/ 14 марта 2011

Это действительно возможно без удаления и добавления аннотации вне курса.

Вам нужно будет наблюдать координату вашего MKAnnotation и обновлять положение MKAnnotationView при его изменении. В качестве альтернативы вы можете (и это, вероятно, более элегантный способ сделать это) получить свои собственные MKAnnotation и MKAnnotationView и сделать их «подвижными».

См. Moving-MKAnnotationView для подробного примера, который также анимирует положение аннотации.

4 голосов
/ 26 апреля 2014

Подкласс MKPointAnnotation, и он имеет возможность автоматически обновлять представление аннотации на карте до новой координаты.

4 голосов
/ 13 марта 2012

Просто используйте КВО:

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

Если ваша MKAnnotation имеет метод setCoordinate, просто включите эти строки прямо здесь:

- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
    [self willChangeValueForKey:@"coordinate"];
    coordinate = newCoordinate;
    [self didChangeValueForKey:@"coordinate"];
}
2 голосов
/ 15 февраля 2010

Не знаю, возможно ли это более широко, но это так, если у вас есть собственный настраиваемый MKAnnotationView.

Мне удалось адаптировать подход, задокументированный в http://spitzkoff.com/craig/?p=108 Крейгом Спицкоффом:

  1. Дайте вашему пользовательскому MKAnnotationView ссылку на ваш объект MKAnnotation
  2. Добавить метод updateCoordinates к объекту MKAnnotation и вызову это когда вы хотите изменить местоположение аннотации
  3. Звони регион, поменял на кастом MKAnnotationView, чтобы сообщить, когда переместить себя (например, когда MKAnnotation обновил координаты)
  4. В DrawRect на внутренний вид объекта принадлежит вашему Пользовательский MKAnnotationView вы можете изменить положение, используя координаты МКАКнотация (вы держите ссылка на него).

Вероятно, вы могли бы еще больше упростить этот подход - вам может не потребоваться объект внутреннего представления при любых обстоятельствах.

1 голос
/ 04 июля 2014

После того, как вы обновите координаты или другие свойства аннотации, просто вызовите следующий метод MKMapViewDelegate, чтобы перерисовать аннотацию:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;

например:.

myAnnotation.coordinate = CLLocationCoordinate2DMake([newLat doubleValue], [newLon doubleValue]);
[self mapView:self.mapView viewForAnnotation:myAnnotation];
1 голос
/ 18 июля 2012

Большинство ответов основаны на том факте, что ваша аннотация была сделана через расширение MKPlacemark. Но как насчет любого другого объекта (то есть пользовательского изображения для маркера), который реализует только протокол MKAnnotation? Не было бы метода setCoordinate. Итак, вот ответ на основе кода, предоставленного 100грамм

    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;

Таким образом, вам в основном нужно получить соответствующий MKAnnotationView, который также может быть достигнут путем итерации по всем аннотациям и его новому местоположению. Я сделал держатель массива для всего этого (NSMutableArray * mapAnnotaions), чтобы теперь я мог выполнять итерации так же, как:

for (id annotation in mapAnnotaions) {call refresh method here for id}
1 голос
/ 16 февраля 2011

Если вы сохраняете ссылку на аннотацию, вносите изменения в свойство координат, а затем снова добавляете аннотацию на карту, местоположение представления аннотации будет обновлено. Вам не нужно удалять аннотацию (что приведет к тому, что вид аннотации на мгновение исчезнет). Это не даст вам хорошего перехода, когда координата аннотации обновляется. Это также не приводит к утечке памяти и к карте не добавляются несколько одинаковых аннотаций (если вы посмотрите на количество аннотаций в виде карты, оно останется постоянным при повторном добавлении аннотации).

0 голосов
/ 01 июля 2010

Взгляните на мой MapKitDragAndDrop образец, он позволяет обновлять MKAnnotation и перемещать MKAnnotationView как на iPhone OS 3, так и на iOS 4 (будет использоваться встроенная поддержка перетаскивания).

...