Можно ли переместить координату MKAnnotation без добавления и удаления аннотации с карты?
Как перемещать MKAnnotation без добавления/удаления его с карты?
Ответ 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];
Почему бы вам не сделать это так?