Можно ли перемещать координату MKAnnotation без добавления и удаления аннотации с карты?
Как переместить MKAnnotation без добавления / удаления с карты?
Я нашел довольно простой метод. Я хотел обновить позицию моего игрока плавно, без удаления, а затем повторно добавив игрок аннотацию. Это хорошо работает для предварительных 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];
}];
Это действительно возможно без удаления и добавления аннотаций отклонения от курса.
Вы должны будете наблюдать за ваше MKAnnotation координаты и обновить позицию MKAnnotationView, когда она меняется. В качестве альтернативы вы можете (и это, пожалуй, более элегантный способ сделать это) получить свой собственный MKAnnotation и MKAnnotationView и сделать их «подвижный».
См Перемещение-MKAnnotationView для подробного примера , который также одушевляет положение аннотации.
Подкласс MKPointAnnotation и имеют возможность обновлять вид аннотаций на карте к новой системе координат автоматически.
Просто используйте КВО:
[annotation willChangeValueForKey:@"coordinate"];
[annotation didChangeValueForKey:@"coordinate"];
Если MKAnnotation имеет метод setCoordinate, просто включить эти строки прямо там:
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
[self willChangeValueForKey:@"coordinate"];
coordinate = newCoordinate;
[self didChangeValueForKey:@"coordinate"];
}
Не знаю, является ли это в более общем плане можно, но если у вас есть свой собственный MKAnnotationView.
Я был в состоянии адаптировать подход документированный в http://spitzkoff.com/craig/?p=108 Крейг Spitzkoff:
- Дайте обычай MKAnnotationView ссылку на ваш объект MKAnnotation
- Добавить метод updateCoordinates к объекту MKAnnotation и вызвать его, когда вы хотите изменить расположение аннотаций
- Вызов RegionChanged на таможенной MKAnnotationView, чтобы сообщить ему, когда изменить себя (например, когда MKAnnotation обновил координаты)
- В DrawRect на внутреннем объекте вида, принадлежащего пользовательских MKAnnotationView вы можете изменить с помощью координат MKAnnotation (вы держите ссылку на него).
Вы, вероятно, можете упростить этот подход дальше - вы не можете требовать внутреннего объекта вида во всех обстоятельствах.
После обновления координат или некоторые другие свойства аннотации, просто вызовите следующий метод MKMapViewDelegate перерисовывать аннотацию:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
например:
myAnnotation.coordinate = CLLocationCoordinate2DMake([newLat doubleValue], [newLon doubleValue]);
[self mapView:self.mapView viewForAnnotation:myAnnotation];
Большинство ответов основаны на том , что аннотации были сделаны с помощью 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'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}
Если вы сохранить ссылку на аннотацию, внести изменения в свойство координат, а затем добавить аннотацию к карте снова, расположение пояснительному будет обновляться. Вам не нужно, чтобы удалить аннотацию (который заставит вид аннотаций на мгновение исчезнуть). Это не даст вам хороший переход для когда аннотации координат обновляется, однако. Он также не приводит к утечке памяти и не существует кратен же аннотация добавляется к карте (если вы посмотрите на количестве аннотаций на MapView, она остается постоянной, когда вы повторно добавить аннотацию).
В Swift 4.0 и IOS 11.0, я просто добавить динамический атрибут координаты свойства дочернего класса класса MKAnnotation и она работает: Все Аннотации MapView обновлять свое местоположение, если значение координаты объектов MKAnnotation обновляются:
class CarAnnotation: NSObject, MKAnnotation {
@objc dynamic var coordinate: CLLocationCoordinate2D
//Add your custom code here
}
Посмотрите на мою MapKitDragAndDrop образца, это позволяет обновлять MKAnnotation и перемещать MKAnnotationView как на iPhone OS 3 и IOS 4 (будет использовать встроенный перетаскиванием поддержки).
Это не представляется возможным изменить координаты объекта MKAnnotation, а затем сообщить MKMapView изменения.
Однако удаление предыдущей аннотацию с карты, меняя координаты вашего объекта аннотаций и добавить его обратно на карту работает хорошо.
[theMapView removeAnnotation:myAnnotation];
[myAnnotation setLatitude:newLatitude];
[theMapView addAnnotation:myAnnotation];
Почему вы не хотите, чтобы сделать это таким образом?













