Este posibil să se mute coordonatele unui MKAnnotation fără a adăuga și îndepărtarea adnotarea de pe hartă?
Cum de a muta un MKAnnotation fără a adăuga / scoate-l de pe hartă?
Am găsit o metodă destul de simplu. Am vrut să actualizeze poziția jucătorului meu lin, fără a scoate și apoi re-adăugarea jucător adnotată. Acest lucru funcționează bine pentru pre-iOS4 aplicații, și ceea ce face este atât muta PIN-ul și centrați harta pe noua locație a PIN-ul lui:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
[UIView commitAnimations];
Aici e același lucru, dar utilizând caracteristica de bloc recomandat pentru iOS4:
[UIView animateWithDuration:0.5 animations:^{
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
}];
Este într-adevăr posibil, fără demontarea și adăugarea de adnotare off-curs.
Va trebui să respecte MKAnnotation dvs. coordoneze și să actualizeze poziția MKAnnotationView atunci când se schimbă. Ca alternativă, puteți (și aceasta este, probabil, cel mai elegant mod de a face asta) derivă propria MKAnnotation și MKAnnotationView și să le facă „mobil“.
A se vedea , Moving-MKAnnotationView un exemplu detaliat care animă și poziția adnotării.
Subclasa MKPointAnnotation și are capacitatea de a actualiza vizualizarea adnotare pe hartă la nou coordonate automat.
Doar utilizați KVO:
[annotation willChangeValueForKey:@"coordinate"];
[annotation didChangeValueForKey:@"coordinate"];
Dacă MKAnnotation are o metoda setCoordinate, includ doar aceste linii acolo:
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
[self willChangeValueForKey:@"coordinate"];
coordinate = newCoordinate;
[self didChangeValueForKey:@"coordinate"];
}
Nu știu dacă e mai general posibil, dar este, dacă aveți propria MKAnnotationView personalizat.
Am fost capabil să se adapteze abordarea documentată la http://spitzkoff.com/craig/?p=108 de Craig Spitzkoff:
- Dă personalizat MKAnnotationView o referință la obiectul dvs. MKAnnotation
- Adăugați o metodă updateCoordinates obiectului MKAnnotation si suna-l atunci când doriți să schimbați locația adnotării
- Apelați regionChanged pe MKAnnotationView personalizat pentru a lăsa să știe când să se repoziționeze (de exemplu, atunci când MKAnnotation a actualizat coordonatele)
- În drawRect asupra obiectului de vedere intern deținut de personalizat MKAnnotationView puteți repoziționa folosind coordonatele MKAnnotation (ții o referire la ea).
Ai putea probabil simplifica această abordare în continuare - ar putea să nu necesita un obiect de vedere intern în toate circumstanțele.
După ce actualizați coordonatele sau alte proprietăți ale adnotărilor, suna doar următoarea metodă MKMapViewDelegate pentru a redesena adnotării:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
de exemplu:
myAnnotation.coordinate = CLLocationCoordinate2DMake([newLat doubleValue], [newLon doubleValue]);
[self mapView:self.mapView viewForAnnotation:myAnnotation];
Cele mai multe răspunsuri se bazează pe faptul că adnotării a fost făcută prin intermediul MKPlacemark se extinde. Dar ce putem spune despre orice alt obiect ( de exemplu , imagine personalizată pentru marcatorul) , care pune în aplicare numai protocolul MKAnnotation? Aceasta nu ar fi metoda setCoordinate. Deci , aici este răspunsul pe baza codului, furnizat de 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;
astfel încât să practic nevoie pentru a obține MKAnnotationView corespunzătoare, care ar putea fi realizat, de asemenea, prin repetare, prin toate adnotări și este noua locație. Am făcut un suport de matrice pentru toate ea (NSMutableArray * mapAnnotaions), așa că acum am putut iterăm la fel ca:
for (id annotation in mapAnnotaions) {call refresh method here for id}
Dacă vă păstrați o trimitere la adnotarea, face o schimbare a proprietății de coordonate, apoi adăugați adnotarea la harta din nou, locația vizualizarea adnotare va fi actualizat. Nu aveți nevoie pentru a elimina adnotarea (ceea ce va determina vizualizarea adnotare să dispară momentan). Acest lucru nu vă va da o tranziție frumos pentru atunci când coordonate este actualizat, dar adnotată. De asemenea, nu are ca rezultat o scurgere de memorie și nici nu există un multiplu de aceeași adnotarea adăugată pe hartă (dacă te uiți la numărul de adnotări pe mapview, rămâne constantă, atunci când readauge adnotare).
În Swift 4.0 și IOS 11.0, am adăuga atribut dinamic la proprietatea de a coordona clasa copil de clasa MKAnnotation și funcționează: Toate Adnotările din MapView actualiza locația lor, dacă coordoneze valoarea obiectelor MKAnnotation sunt actualizate:
class CarAnnotation: NSObject, MKAnnotation {
@objc dynamic var coordinate: CLLocationCoordinate2D
//Add your custom code here
}
Aruncati o privire la meu MapKitDragAndDrop probă, vă permite să actualizați MKAnnotation și pentru a muta MKAnnotationView pe ambele iPhone OS 3 și iOS 4 ( se va utiliza suport încorporat glisarea).
Nu pare posibil să se schimbe coordonatele unui obiect MKAnnotation și informează apoi MKMapView schimbării.
Cu toate acestea, eliminarea adnotarea anterioare de pe hartă, schimbarea obiectului coordonatei adnotări și adăugarea înapoi la harta funcționează bine.
[theMapView removeAnnotation:myAnnotation];
[myAnnotation setLatitude:newLatitude];
[theMapView addAnnotation:myAnnotation];
De ce nu vrei să o faci în acest fel?













