Er det mulig å flytte koordinere en MKAnnotation uten å legge til og fjerne merknaden fra kartet?
Slik flytter en MKAnnotation uten å legge til / fjerne det fra kartet?
Jeg fant en ganske enkel metode. Jeg ønsket å oppdatere min spillerens posisjon jevnt uten å fjerne og deretter legge spilleren merknader. Dette fungerer godt for pre-iOS4 apps, og hva den gjør er både flytte pinnen og sentrere kartet på pinnen er nytt sted:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
[UIView commitAnimations];
Her er den samme, men bruker den anbefalte blokk funksjonen for iOS4:
[UIView animateWithDuration:0.5 animations:^{
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
}];
Det er faktisk mulig uten å fjerne og legge til merknaden off-kurs.
Du må observere din MKAnnotation koordinatsystem og oppdatere MKAnnotationView posisjon når den endres. Alternativt kan du (og dette er trolig den mer elegant måte å gjøre det) utlede din egen MKAnnotation og MKAnnotationView og gjøre dem "bevegelig".
Se Flytte-MKAnnotationView for et detaljert eksempel som også animerer plasseringen av merknaden.
Underklasse MKPointAnnotation og den har evnen til å oppdatere merknaden syn på kartet til den nye koordinere automatisk.
Bare bruk KVO:
[annotation willChangeValueForKey:@"coordinate"];
[annotation didChangeValueForKey:@"coordinate"];
Hvis MKAnnotation har en setCoordinate metode, bare inkludere disse linjene der:
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
[self willChangeValueForKey:@"coordinate"];
coordinate = newCoordinate;
[self didChangeValueForKey:@"coordinate"];
}
I Swift 4.0 og IOS 11,0, jeg bare legge til dynamisk attributt til koordinere tilhører barnets klasse MKAnnotation klasse og det fungerer: Alle merknader på MapView oppdatere sin plassering hvis koordinere verdien av MKAnnotation objekter er oppdatert:
class CarAnnotation: NSObject, MKAnnotation {
@objc dynamic var coordinate: CLLocationCoordinate2D
//Add your custom code here
}
Vet ikke om det er mer generelt mulig, men det er hvis du har din egen custom MKAnnotationView.
Jeg var i stand til å tilpasse seg den tilnærmingen dokumentert på http://spitzkoff.com/craig/?p=108 av Craig Spitzkoff:
- Gi din egendefinerte MKAnnotationView en referanse til MKAnnotation objekt
- Legg en updateCoordinates metode til MKAnnotation objekt og kaller det når du ønsker å endre plasseringen av merknaden
- Ring regionChanged på tilpasset MKAnnotationView å gi beskjed om å flytte seg selv (for eksempel når MKAnnotation har oppdatert koordinater)
- I drawRect på intern visning objekt som eies av den tilpassede MKAnnotationView du kan flytte ved hjelp av koordinatene til MKAnnotation (du holder en referanse til det).
Du kan sannsynligvis forenkle denne tilnærmingen videre - du kan ikke kreve en intern visning objekt i alle situasjoner.
Når du har oppdatert koordinatene eller noen andre egenskaper for merknader, bare ringe følgende MKMapViewDelegate metode for å tegne din merknad:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
f.eks:
myAnnotation.coordinate = CLLocationCoordinate2DMake([newLat doubleValue], [newLon doubleValue]);
[self mapView:self.mapView viewForAnnotation:myAnnotation];
De fleste svarene er basert på faktum at merknad er gjort via MKPlacemark utvide. Men hva med alle andre objekt (dvs. egendefinert bilde for markør) som bare implementerer MKAnnotation protokoll? Det ville ikke ha setCoordinate metoden. Så her er svaret basert på kode, levert av 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;
Så du i utgangspunktet trenger for å få tilsvarende MKAnnotationView som kan også oppnås ved iterasjon via alle merknader og den nye plasseringen. Jeg gjorde en rekke holder for alt (NSMutableArray * mapAnnotaions) så nå kunne jeg gjenta bare liker:
for (id annotation in mapAnnotaions) {call refresh method here for id}
Hvis du holder en referanse til kommentaren, gjør en endring i koordinere eiendom, og deretter legge merknaden til kartet igjen, plasseringen av merknaden visningen vil oppdatere. Du trenger ikke å fjerne merknaden (som vil føre til at merknaden tanke på et øyeblikk forsvinner). Dette vil ikke gi deg en fin overgang for når merknaden koordinere oppdateres imidlertid. Det heller ikke resultere i en minnelekkasje eller er det et multiplum av den samme merknaden lagt til kartet (hvis du ser på antall kommentarer på mapview, forblir det konstant når du re-legge merknaden).
Ta en titt på min MapKitDragAndDrop prøve, det kan du oppdatere MKAnnotation og flytte MKAnnotationView på både iPhone OS 3 og iOS 4 (vil bruke innebygde dra støtte).
Det synes ikke mulig å endre koordinatene for en MKAnnotation objekt og deretter informere MKMapView av endringen.
Men å fjerne den forrige merknaden fra kartet, endre koordinatene for din merknad objekt og legge den tilbake til kartet fungerer godt.
[theMapView removeAnnotation:myAnnotation];
[myAnnotation setLatitude:newLatitude];
[theMapView addAnnotation:myAnnotation];
Hvorfor ønsker du ikke å gjøre det på denne måten?













