Подтвердить что ты не робот

Как перемещать MKAnnotation без добавления/удаления его с карты?

Можно ли переместить координату MKAnnotation без добавления и удаления аннотации с карты?

4b9b3361

Ответ 1

Я нашел довольно простой метод. Я хотел обновить позицию своего игрока плавно, не удаляя, а затем повторно добавляя аннотацию игрока. Это хорошо работает для приложений pre-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];
}];

Ответ 2

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

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

Подробнее см. Moving-MKAnnotationView, который также оживляет позицию аннотации.

Ответ 3

Просто используйте KVO:

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

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

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

Ответ 4

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

Ответ 5

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

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

  • Предоставьте свой собственный MKAnnotationView ссылку на объект MKAnnotation.
  • Добавить метод updateCoordinates к объекту MKnnotation и вызову это когда вы хотите изменить местоположение аннотации
  • Вызовите областьChanged на пользовательском MKAnnotationView, чтобы сообщить, когда переместить себя (например, когда Обновлено MKAnnotation координаты)
  • В drawRect на объект внутреннего вида, принадлежащий вашему Пользовательский MKAnnotationView вы можете с помощью координат MKAnnotation (вы держите ссылка на него).

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

Ответ 6

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

Ответ 7

Большинство ответов основано на том факте, что ваша аннотация была сделана с помощью расширения MKPlacemark. Но как насчет любого другого объекта (т.е. Пользовательского изображения для маркера), который реализует протокол MKAnnotation? У него не было бы метода setCoordinate. Итак, вот ответ, основанный на коде, предоставляемый 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 move
        static NSString *[email protected]"positionAnimation";
    static NSString *[email protected]"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}

Ответ 8

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

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

например:.

myAnnotation.coordinate = CLLocationCoordinate2DMake([newLat doubleValue], [newLon doubleValue]);
[self mapView:self.mapView viewForAnnotation:myAnnotation];

Ответ 9

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

Ответ 10

Невозможно изменить координату объекта MKAnnotation, а затем сообщить MKMapView об изменении.

Однако удаление предыдущей аннотации с карты, изменение координаты объекта аннотации и добавление ее обратно на карту хорошо работают.

[theMapView removeAnnotation:myAnnotation]; 
[myAnnotation setLatitude:newLatitude];
[theMapView addAnnotation:myAnnotation];

Почему бы вам не сделать это так?