Czy to możliwe, aby przesunąć współrzędna MKAnnotation bez dodawania i usuwania adnotacji z mapy?
Jak przenieść MKAnnotation bez dodawania / usuwania go z mapy?
Znalazłem dość prosty sposób. Chciałem aktualizować pozycję mojego odtwarzacza płynnie bez zdejmowania i ponowne dodanie adnotacji gracza. Działa to dobrze dla iOS4 wstępnych aplikacji i co robi to zarówno przesunąć trzpień i wyśrodkować mapę na kołku w nowym miejscu:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
[UIView commitAnimations];
Tutaj jest to samo, ale stosując zalecaną funkcję bloku dla iOS4:
[UIView animateWithDuration:0.5 animations:^{
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
}];
To jest rzeczywiście możliwe bez usuwanie i dodawanie adnotacji off-oczywiście.
Musisz obserwować MKAnnotation układzie współrzędnych i aktualizuje pozycję MKAnnotationView kiedy zmienia. Alternatywnie może (i to jest chyba bardziej elegancki sposób to zrobić) czerpią swoją MKAnnotation i MKAnnotationView i uczynić je „ruchomy” ty.
Zobacz ruchomą MKAnnotationView do szczegółowego przykładu, który ożywia także pozycję adnotacji.
Podklasa MKPointAnnotation i ma zdolność do aktualizacji widoku opisu na mapie, aby nowa koordynować automatycznie.
Wystarczy użyć KVO:
[annotation willChangeValueForKey:@"coordinate"];
[annotation didChangeValueForKey:@"coordinate"];
Jeśli MKAnnotation ma metodę setCoordinate, po prostu zawierać te linie tam:
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
[self willChangeValueForKey:@"coordinate"];
coordinate = newCoordinate;
[self didChangeValueForKey:@"coordinate"];
}
Nie wiem, czy to możliwe, bardziej ogólnie, ale jeśli masz swój własny MKAnnotationView.
Udało mi się dostosować podejście udokumentowany w http://spitzkoff.com/craig/?p=108 Craig Spitzkoff:
- Daj niestandardowego MKAnnotationView odniesienie do obiektu MKAnnotation
- Dodaj metodę updateCoordinates do obiektu MKAnnotation i nazwać to, gdy chcesz zmienić lokalizację adnotacją
- Zadzwoń regionChanged na zamówienie MKAnnotationView do niech wiedzą, kiedy przesunąć się (np podczas MKAnnotation uaktualnili współrzędnych)
- W drawRect na wewnętrznej obiektu widoku należącego swoim zwyczajem MKAnnotationView Możesz zmienić za pomocą współrzędnych MKAnnotation (trzymasz odniesienie do niego).
Można prawdopodobnie uprości to podejście dalej - nie może wymagać wewnętrzny obiekt widoku w każdych okolicznościach.
Po zaktualizowaniu współrzędne lub niektóre inne właściwości adnotacji, wystarczy zadzwonić następujące metody MKMapViewDelegate przerysować swoją adnotację:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
na przykład:
myAnnotation.coordinate = CLLocationCoordinate2DMake([newLat doubleValue], [newLon doubleValue]);
[self mapView:self.mapView viewForAnnotation:myAnnotation];
Większość odpowiedzi opierają się na fakcie, że Adnotacja została dokonana poprzez MKPlacemark rozszerzenie. Ale co każdy inny obiekt (czyli niestandardowego obrazu dla markera), który implementuje protokół MKAnnotation tylko? To nie miałoby metodę setCoordinate. Więc tutaj jest odpowiedzią na podstawie kodu, pod warunkiem przez 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;
Zasadniczo więc trzeba uzyskać odpowiedni MKAnnotationView które mogłyby być również osiągnięty przez iteracji za pośrednictwem wszystkich adnotacji i jest to nowa lokalizacja. Zrobiłem uchwyt tablicy na to wszystko (NSMutableArray * mapAnnotaions), więc teraz mogę iteracyjne prostu lubię:
for (id annotation in mapAnnotaions) {call refresh method here for id}
Jeśli zachować odniesienie do adnotacji, dokonać zmiany właściwości współrzędnych, a następnie dodać adnotację na mapie znowu położenie widoku opisu zaktualizuje. Nie trzeba usunąć adnotację (co spowoduje widok adnotacji na chwilę zniknąć). To nie daje piękny przejście dla kiedy współrzędnych adnotacja jest aktualizowana jednak. To również nie doprowadzić do wycieku pamięci, ani nie są wielokrotnością tej samej adnotacji dodana do mapy (jeśli spojrzeć na liczby adnotacji na MapView, pozostaje na stałym poziomie, gdy ponownie dodać adnotację).
W Swift 4.0 i IOS 11.0, po prostu dodać atrybut dynamiczny do nieruchomości współrzędnych klasy podrzędnej klasy MKAnnotation i to działa: Wszystkie adnotacje na MapView aktualizować swoją lokalizację, jeśli wartość współrzędnych obiektów MKAnnotation zostały zaktualizowane:
class CarAnnotation: NSObject, MKAnnotation {
@objc dynamic var coordinate: CLLocationCoordinate2D
//Add your custom code here
}
Spójrz na moją MapKitDragAndDrop próby, pozwala na aktualizację MKAnnotation i przenieść MKAnnotationView zarówno iPhone OS 3 i iOS 4 (użyje wbudowaną obsługę przeciągania).
To nie wydaje się możliwe, aby zmienić współrzędne obiektu MKAnnotation a następnie informuje MKMapView zmiany.
Jednak usunięcie poprzedniej adnotacji z mapy, zmieniając współrzędnych Twojego obiektu adnotacji i dodanie go do mapy działa dobrze.
[theMapView removeAnnotation:myAnnotation];
[myAnnotation setLatitude:newLatitude];
[theMapView addAnnotation:myAnnotation];
Dlaczego nie chcesz zrobić to w ten sposób?













