Dorit: Cum fiabil, selectați în mod constant o adnotare MKMapView

voturi
29

După apelarea MKMapView lui setCenterCoordinate: animat: metoda (fără animație), aș dori să numesc selectAnnotation: animat: (cu animație) , astfel încât adnotarea iese din piunezei nou-centrat.

Deocamdată, mă uit pur și simplu pentru mapViewDidFinishLoadingMap: și apoi selectați adnotarea. Cu toate acestea, acest lucru este problematic. De exemplu, această metodă nu este numit atunci când nu este nevoie să se încarce date suplimentare hartă. În aceste cazuri, adnotare mea nu este selectată.:(

Foarte bine. Am putea numi acest lucru imediat după setarea centrului de coordonate în loc. Ahh, dar în acest caz , este posibil ca nu este de date de pe hartă pentru a încărca (dar nu și- a terminat de încărcat încă). Mi - ar risca numindu - l prea devreme, cu animația devine spotty cel mai bun caz .

Astfel, dacă am înțeles corect, nu este o chestiune de a ști dacă meu de coordonate este vizibil, deoarece este posibil să se abată aproape de distanță și de ecran plin trebuie să încarce date noi hartă. Mai degrabă, este o chestiune de a ști dacă date hartă trebuie să fie încărcate, și apoi acționează în consecință.

Orice idei cu privire la modul de a realiza acest lucru, sau cum se în alt mod (fiabil) selectați o adnotare după re-centrarea pe harta coordonatei unde care trăiește adnotare?

Indiciile apreciat - mulțumiri!

Întrebat 10/08/2009 la 20:53
sursa de către utilizator
În alte limbi...                            


7 răspunsuri

voturi
36

Am fugit în aceeași problemă, dar nu a găsit ceea ce pare a fi o soluție fiabilă și rezonabilă:

  1. Punerea în aplicare a delegat metoda mapView: didAddAnnotationViews :. Când am încercat selectarea adnotare direct în cadrul metodei delegarii, a scăzut cu înștiințarea PIN-ul! Asta se uită ciudat, așa că am adăuga o mică întârziere de o jumătate de secundă.

    -(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
        [self performSelector:@selector(selectInitialAnnotation)
              withObject:nil afterDelay:0.5];
    }
    
  2. Selectați adnotarea inițială așa cum te-ai aștepta, dar selectAnnotation de asteptare: animat;

    -(void)selectInitialAnnotation {
        [self.mapView selectAnnotation:self.initialAnnotation animated:YES];
    }
    

Se pare că selectAnnotation:animated:nu este numit în anumite condiții. Compara cu documente MKMapView :

În cazul în care nu este specificat adnotarea de pe ecran, și, prin urmare, nu are o vedere adnotare asociată, această metodă nu are nici un efect.

Publicat 16/02/2010 la 01:06
sursa de către utilizator

voturi
7

Un mod mai coerent decât utilizarea unui timeout fix este de a asculta regionDidChangeapel invers. Setați coordona centrul hărții la adnotarea dorită, iar atunci când metoda regionDidChange se numește, apoi selectați adnotarea în centru, pentru a deschide înștiințarea.

Iată un mic film am luat de lucru care rulează în mod aleatoriu între 5 pini.

În primul rând, centrul de coordonate mergeti adnotării. Să presupunem că obiectul adnotare este numit thePin.

- (void)someMethod {
    [map setCenterCoordinate:thePin.coordinate animated:YES];
}

Apoi , în regionDidChangemetoda, selectați această adnotare.

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    [map selectAnnotation:thePin animated:YES];
}
Publicat 12/11/2010 la 06:23
sursa de către utilizator

voturi
4

Ei bine doar FYI, aceasta este ceea ce spun docs,

În cazul în care nu este specificat adnotarea de pe ecran, și, prin urmare, nu are o vedere adnotare asociată, această metodă nu are nici un efect.

Deci , dacă vreau să sun setCenterCoordinate:animated:sau setRegion:animated:și apoi vreau să selectați adnotarea prin apelarea, selectAnnotation:animated:, adnotarea nu va fi selectată și nu va apărea înștiințarea beacause de exact același motiv menționat mai sus în documente, deci modul în care aceasta ar fi mare de a avea ceva de genul, setCenterCoordinate:animated:ComletionBlockdar ei nu sunt acolo ..! Modul în care a lucrat pentru mine este ca mai jos,

 [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut animations:^{
        [self.mapView setCenterCoordinate:location.coordinate animated:YES];
    } completion:^(BOOL finished) {
        [self.mapView selectAnnotation:location animated:YES];
    }];

Acest lucru vă va da un bloc de finalizare și u pot folosi pentru a selecta adnotarea.

Publicat 14/08/2013 la 06:43
sursa de către utilizator

voturi
4

Ceea ce a lucrat pentru mine a fost sunat selectAnnotation:animated:de la mapView:didAddAnnotationViews:metoda:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
{
    [mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
}

Documentația Apple același lucru aici .

Rețineți că am avut doar o adnotare pe hartă , astfel a [[mapView annotations] lastObject]fost bine pentru scopurile mele. Kilometraj dvs. poate varia.

Publicat 02/11/2009 la 19:44
sursa de către utilizator

voturi
2

Am avut o problemă similară. Am fost folosind MKPinAnnotationView implicit cu animatesDrop: DA. După ce am adăugat adnotările la MKMapView, am fost de a face acest lucru:

[mapView selectAnnotation:[mapView.annotations objectAtIndex:1] animated:YES]

care, în logica programului meu, ar trebui să aleagă cea mai apropiată adnotată. Acest lucru nu a fost de lucru. M-am gândit motivul: vizualizarea adnotare nu a fost pe ecran la momentul acestui apel, selectați, din cauza animație PIN-ul picătură. Așa că tot ce am făcut a fost stabilit un cronometru pentru a selecta adnotarea o secundă mai târziu. E un hack, dar funcționează. Nu sunt sigur dacă va funcționa în orice situație, deși, de exemplu, pe un 3G vs 3Gs. Ar fi mai bine să dau seama funcția de apel invers dreptul să-l pună în.

selectTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self
               selector:@selector(selectClosestAnnotation) userInfo:nil
               repeats:NO];

- (void)selectClosestAnnotation {
    [mapView selectAnnotation:[mapView.annotations objectAtIndex:1]
             animated:YES];
}
Publicat 15/12/2009 la 18:49
sursa de către utilizator

voturi
1

Am găsit mai multe probleme cu toate soluțiile am văzut pentru problema mea (am dori să selectați o adnotare când l-am adăugat la viewDidAppear):

  1. Folosind mapView:didAddAnnotationViews:metoda delegat.

    Acest lucru nu a funcționat pentru mine, pentru că în cazul în care nu este specificat adnotarea de pe ecran, și, prin urmare, nu are o vedere adnotare asociată, această metodă nu are nici un efect.

  2. Folosind mapViewDidFinishLoadingMap:metoda delegat.

    Acest lucru nu a funcționat pentru mine, fie pentru că harta este în cache acum, deci metoda este numit doar o singură dată, prima dată.

Soluţie:

John Blackburn a fost foarte aproape , dar fără mapView:didAddAnnotationViews:metodă. Doar eu numesc propria mea selectAnnotation:metodă, înainte de a adăuga adnotare, cu o întârziere:

[self.mapView addAnnotation:ann];
[self performSelector:@selector(selectAnnotation:) withObject:ann afterDelay:0.5];

Și asta este ceea ce fac eu în mea selectAnnotation:metodă:

- (void)selectAnnotation:(id < MKAnnotation >)annotation
{
   [self.mapView selectAnnotation:annotation animated:YES];
}

Testat pe două iPhone 3GS (iOS 5 și 6) și un iPhone 5.

Publicat 23/10/2012 la 09:31
sursa de către utilizator

voturi
0

Am fost cu dificultăți similare, dar a fost de fapt nu a putut face această metodă de lucru, la toate, să nu mai vorbim inconsecvent.

Iată ce am găsit la locul de muncă. Poate că va lucra pentru tine: Cum de a declanșa vederea înștiințărilor MKAnnotationView lui , fără a atinge PIN - ul?

Publicat 24/08/2009 la 03:53
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more