Recherché: Comment fiable, sélectionner systématiquement une annotation MKMapView

voix
29

Après avoir appelé MKMapView de setCenterCoordinate: animation: méthode (sans animation), je voudrais appeler selectAnnotation: animation: (avec animation) , de sorte que l'annotation ressorte du nouveau centrée pushpin.

Pour l' instant, je regarde simplement mapViewDidFinishLoadingMap: puis sélectionnez l'annotation. Cependant, cela pose problème. Par exemple, cette méthode est appelée quand il n'y a pas besoin de charger des données cartographiques supplémentaires. Dans ces cas, mon annotation n'est pas sélectionnée.:(

Très bien. Je pourrais appeler immédiatement après avoir réglé le centre de coordonnées à la place. Ahh, mais dans ce cas , il est possible qu'il y est des données de carte pour charger (mais il n'a pas encore fini de chargement). Je risquais appeler trop tôt, avec l'animation devient inégale au mieux.

Ainsi, si je comprends bien, ce n'est pas une question de savoir si ma coordonnée est visible, car il est possible de s'écarter presque de la distance et page d' écran doivent charger de nouvelles données cartographiques. Au contraire, il est une question de savoir si les nouvelles données de carte doit être chargé, puis agir en conséquence.

Toutes les idées sur la façon d'y parvenir, ou comment autrement (fiable) sélectionner une annotation après re-centrer la vue sur la carte de la coordonnée où cette vie d'annotation?

Clues apprécié - merci!

Créé 10/08/2009 à 20:53
source utilisateur
Dans d'autres langues...                            


7 réponses

voix
36

Je suis tombé sur le même problème, mais trouvé ce qui semble être une solution fiable et raisonnable:

  1. Mettre en oeuvre le procédé délégué Mapview: didAddAnnotationViews :. Quand j'ai essayé sélectionner l'annotation directement dans la méthode délégué, la légende a chuté à la broche! Cela avait l'air bizarre, donc j'ajouter un léger retard d'une demi-seconde.

    -(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
        [self performSelector:@selector(selectInitialAnnotation)
              withObject:nil afterDelay:0.5];
    }
    
  2. Sélectionnez l'annotation initiale que vous attendez, mais appeler selectAnnotation: animation;

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

Il semble que selectAnnotation:animated:non appelé dans certaines conditions. Comparer avec MKMapView docs :

Si l'annotation spécifiée n'est pas à l'écran, et n'a donc pas une vue d'annotation associée, cette méthode n'a aucun effet.

Créé 16/02/2010 à 01:06
source utilisateur

voix
7

Une façon plus cohérente que l' utilisation d' un délai fixe est d'écouter le regionDidChangerappel. Définissez le centre de coordonnées de la carte à l'annotation désirée, et lorsque la méthode regionDidChange est appelée, puis sélectionnez l'annotation dans le centre, pour ouvrir la légende.

Voici une petite vidéo que je pris la chose en cours d' exécution au hasard entre 5 broches.

Tout d' abord, goto coordonnées du centre de l'annotation. Disons que l'objet d'annotation est nommé thePin.

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

Puis , dans la regionDidChangeméthode, sélectionnez cette annotation.

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    [map selectAnnotation:thePin animated:YES];
}
Créé 12/11/2010 à 06:23
source utilisateur

voix
4

Eh bien simplement votre information, c'est ce que disent les documents,

Si l'annotation spécifiée n'est pas à l'écran, et n'a donc pas une vue d'annotation associée, cette méthode n'a aucun effet.

Donc , si je veux appeler setCenterCoordinate:animated:ou setRegion:animated:puis je veux choisir l'annotation en appelant, selectAnnotation:animated:l'annotation ne sera pas sélectionnée et la légende n'apparaîtra beacause de l'exacte même raison mentionnée ci - dessus dans docs, donc la façon dont il serait super d'avoir quelque chose comme, setCenterCoordinate:animated:ComletionBlockmais ce ne est pas là ..! La façon dont a fonctionné pour moi est comme ci - dessous,

 [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];
    }];

Cela vous donnera un bloc d'achèvement et u peut utiliser pour sélectionner l'annotation.

Créé 14/08/2013 à 06:43
source utilisateur

voix
4

Ce qui a fonctionné pour moi appelai selectAnnotation:animated:de la mapView:didAddAnnotationViews:méthode:

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

Documentation Apple sur le même ici .

Notez que je n'avais qu'une annotation sur la carte afin [[mapView annotations] lastObject]était très bien pour mes besoins. Votre kilométrage peut varier.

Créé 02/11/2009 à 19:44
source utilisateur

voix
2

J'avais un problème similaire. J'utilisais le MKPinAnnotationView par défaut avec animatesDrop: OUI. Après avoir ajouté les annotations au MKMapView, je faisais ceci:

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

qui, dans la logique de mon programme, devrait choisir la plus proche annotation. Ce ne fonctionnait pas. Je me suis dit la raison: la vue d'annotation était pas à l'écran au moment de cette sélection appel, en raison de l'animation de chute de la broche. Donc, tout ce que je l'ai été mis une minuterie pour sélectionner l'annotation d'une seconde plus tard. Il est un hack, mais cela fonctionne. Je ne sais pas si ça va marcher dans toutes les situations que, par exemple sur un réseau 3G vs 3Gs. Il serait préférable de comprendre la fonction de rappel droit de le mettre dans.

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

- (void)selectClosestAnnotation {
    [mapView selectAnnotation:[mapView.annotations objectAtIndex:1]
             animated:YES];
}
Créé 15/12/2009 à 18:49
source utilisateur

voix
1

J'ai trouvé plusieurs problèmes avec toutes les solutions que je voyais mon problème (je veux choisir une annotation quand je l'ai ajouté de viewDidAppear):

  1. Utilisation de la mapView:didAddAnnotationViews:méthode déléguée.

    Cela n'a pas fonctionné pour moi parce que si l'annotation spécifiée n'est pas à l'écran, et ne dispose donc pas une vue d'annotation associée, cette méthode n'a aucun effet.

  2. Utilisation de la mapViewDidFinishLoadingMap:méthode déléguée.

    Cela ne fonctionne pas pour moi non plus parce que la carte est mise en mémoire cache maintenant la méthode est appelée une seule fois, la première fois.

Solution:

John Blackburn était très proche , mais sans la mapView:didAddAnnotationViews:méthode. Je viens d' appeler ma propre selectAnnotation:méthode, avant d' ajouter l'annotation, avec un retard:

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

Et ce que je fais dans ma selectAnnotation:méthode:

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

Testé sur deux 3GS (iOS 5 et 6) et un iPhone 5.

Créé 23/10/2012 à 09:31
source utilisateur

voix
0

J'avais des difficultés similaires, mais était en fait pas en mesure de faire fonctionner cette méthode du tout, et encore moins de manière incohérente.

Voici ce que j'ai trouvé au travail. Peut - être que cela fonctionnera pour vous aussi: Comment déclencher la vue de MKAnnotationView callout sans toucher la broche?

Créé 24/08/2009 à 03:53
source utilisateur

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