Ist es möglich, die Koordinate eines MKAnnotation ohne das Hinzufügen und Entfernen der Anmerkung aus der Karte zu bewegen?
Wie ein MKAnnotation ohne das Hinzufügen / Entfernen aus der Karte bewegen?
Ich fand ein ziemlich einfaches Verfahren. Ich wollte, dass meine Spieler die Position glatt, ohne zu entfernen und dann erneut Hinzufügen der Spieler Anmerkung aktualisieren. Das funktioniert gut für Pre-iOS4 Apps und was es tut, ist sowohl den Stift bewegen und in der Mitte der Karte auf dem neuen Standort des pin:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
[UIView commitAnimations];
Hier ist das Gleiche, aber die empfohlene Block-Funktion für iOS4 mit:
[UIView animateWithDuration:0.5 animations:^{
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
}];
Es ist in der Tat möglich, ohne zu entfernen und das Hinzufügen der Annotation off-Kurs.
Sie müssen Ihre MKAnnotation beobachten, die die Position des MKAnnotationView koordinieren und aktualisieren, wenn sie sich ändert. Alternativ können Sie auch (und das ist wahrscheinlich die elegantere Art und Weise, es zu tun) leiten Sie Ihre eigene MKAnnotation und MKAnnotationView und machen sie „beweglich“.
Siehe Moving-MKAnnotationView für ein detailliertes Beispiel , das auch die Position der Anmerkung beseelt.
Subclass MKPointAnnotation und es hat die Fähigkeit, die Anmerkungsansicht auf der Karte auf die neue Koordinate automatisch zu aktualisieren.
Verwenden Sie einfach KVO:
[annotation willChangeValueForKey:@"coordinate"];
[annotation didChangeValueForKey:@"coordinate"];
Wenn Ihr MKAnnotation eine setCoordinate Methode hat, sind gerade diese Zeilen genau dort:
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
[self willChangeValueForKey:@"coordinate"];
coordinate = newCoordinate;
[self didChangeValueForKey:@"coordinate"];
}
Sie wissen nicht, ob es grundsätzlich möglich ist, aber es ist, wenn Sie Ihre eigenen MKAnnotationView haben.
Ich konnte den Ansatz an dokumentiert anzupassen http://spitzkoff.com/craig/?p=108 von Craig Spitzkoff:
- Geben Sie Ihren benutzerdefinierten MKAnnotationView einen Verweis auf Ihr MKAnnotation Objekt
- Fügen Sie ein updateCoordinates Verfahren zum MKAnnotation Objekt und rufen es, wenn Sie Position des Kommentars ändern möchten
- Rufen Sie Region auf dem benutzerdefinierten MKAnnotationView es wissen zu lassen, wenn sich neu zu positionieren (zB bei MKAnnotation aktualisiert Koordinaten)
- In drawRect auf dem Objekt Innenansicht von Ihrer benutzerdefinierten Besitz MKAnnotationView Sie mit den Koordinaten des MKAnnotation neu positionieren können (Sie halten einen Verweis darauf).
Sie könnten wahrscheinlich diesen Ansatz weiter vereinfachen - Sie können nicht eine interne Ansicht Objekt unter allen Umständen erfordern.
Nachdem Sie die Koordinaten oder einige andere Eigenschaften der Anmerkung aktualisieren, rufen Sie einfach MKMapViewDelegate Methode nach Ihrer Anmerkung neu zu zeichnen:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
z.B:
myAnnotation.coordinate = CLLocationCoordinate2DMake([newLat doubleValue], [newLon doubleValue]);
[self mapView:self.mapView viewForAnnotation:myAnnotation];
Die meisten Antworten sind auf Tatsache , dass Ihre Annotation wurde über MKPlacemark erstreckt gemacht worden. Aber was ist ein anderes Objekt (dh benutzerdefiniertes Bild für Marker) , die nur MKAnnotation Protokoll implementiert? Es wäre nicht die setCoordinate Methode hat. So , hier ist die Antwort basierend auf Code, der von einem 100 Gramm
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;
so müssen Sie im Grunde die entsprechenden MKAnnotationView zu erhalten, die auch durch Iteration über alle Anmerkungen erreicht werden könnte, und es ist neue Position. Ich habe ein Array Halter für alle von ihm (NSMutableArray * mapAnnotaions) so jetzt konnte ich nur wiederholen mag:
for (id annotation in mapAnnotaions) {call refresh method here for id}
Wenn Sie einen Verweis auf Ihre Anmerkung zu halten, machen eine Änderung der Koordinaten Eigenschaft, dann die Anmerkung wieder auf der Karte hinzufügen, wird die Lage der Anmerkungsansicht aktualisieren. Sie brauchen nicht die Anmerkung zu entfernen (die die Anmerkungsansicht wird dazu führen, dass für einen Moment verschwinden). Dies wird nicht einen schönen Übergang für geben, wenn die Anmerkung Koordinaten jedoch aktualisiert. Es ist auch nicht zu einem Speicherverlust zur Folge hat, noch gibt es ein Vielfaches der gleichen Anmerkung zur Karte hinzugefügt (wenn man sich die Anzahl der Anmerkungen auf dem mapview aussehen, bleibt es konstant, wenn Sie die Anmerkung erneut hinzufügen).
In Swift 4.0 und IOS 11.0, füge ich nur dynamisches Attribut auf die Koordinaten Eigenschaft der Kinderklasse MKAnnotation Klasse und es funktioniert: Alle Anmerkungen auf MapView ihren Standort aktualisieren, wenn der Wert von MKAnnotation Objekten koordinieren aktualisiert:
class CarAnnotation: NSObject, MKAnnotation {
@objc dynamic var coordinate: CLLocationCoordinate2D
//Add your custom code here
}
Werfen Sie einen Blick auf meine MapKitDragAndDrop Probe, ermöglicht es Ihnen MKAnnotation und bewegen MKAnnotationView auf iPhone OS 3 und iOS 4 (wird verwenden Einbau-Ziehen - Unterstützung) zu aktualisieren.
Es scheint nicht möglich, die Koordinate eines MKAnnotation Objekts zu ändern und dann die MKMapView der Änderung informieren.
Um jedoch die vorherige Anmerkung aus der Karte zu entfernen, ändern die Ihre Annotierungsobjekt koordinieren und es zurück zu der Karte hinzugefügt gut funktioniert.
[theMapView removeAnnotation:myAnnotation];
[myAnnotation setLatitude:newLatitude];
[theMapView addAnnotation:myAnnotation];
Warum wollen Sie nicht es auf diese Weise zu tun?













