Gros problème géolocalisation

AdamAdam Membre
04:20 modifié dans Vos applications #1
Bonjour,
Cela fait au moins une semaine que je suis bloqué sur mon programme de géolocalisation.
Mon but est de faire un programme assez simple avec des points d'intérêts sur une carte, qui renvoient à  des sites web.

Chaque annotation (point d'intérêt), est associé à  un identifiant précis. 
Puis chaque annotation est liée à  un bouton (dans (MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation) grâce à  mon identifiant.
j'ai alors : monannotation.identifiant=bouton.tag...

Le tout me semble correct, mais lorsque dans mon selector de mon bouton, je veux trier mes résultats (pour associer la bonne annotation au bon site web), il mélange tout les identifiants. Et donc l'association se fait pas correctement.



Jai une classe monAnnotation (pour initialiser l'annotation avec mapKit).

Et le reste du code se trouve dans RootViewController.h :



<br />@implementation RootViewController<br /><br /><br />- (void)viewDidLoad<br />{<br />&nbsp; &nbsp; maMapView=[[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 360)];<br />&nbsp; &nbsp; maMapView.showsUserLocation=YES;<br />&nbsp; &nbsp; maMapView.mapType=MKMapTypeHybrid;<br />&nbsp; &nbsp; maMapView.delegate=self;<br />&nbsp; &nbsp; [self.view addSubview:maMapView];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; //Declaration du Label affichant l&#039;adresse actuelle de l&#039;utilisateur<br />&nbsp; &nbsp; labelReverseGeocoder=[[UILabel alloc] initWithFrame:CGRectMake(20, 380, 280, 40)];<br />&nbsp; &nbsp; [self.view addSubview:labelReverseGeocoder];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; //Declaration du bouton qui va lancer le reverse geo coder<br />&nbsp; &nbsp; buttonLaunchReverseGeocode=[UIButton buttonWithType:UIButtonTypeRoundedRect];<br />&nbsp; &nbsp; buttonLaunchReverseGeocode.frame=CGRectMake(20, 420, 150, 30);<br />&nbsp; &nbsp; [buttonLaunchReverseGeocode setTitle:@&quot;Mon adresse&quot; forState:UIControlStateNormal];<br />&nbsp; &nbsp; [buttonLaunchReverseGeocode addTarget:self action:@selector(reverseGeocodeCurrentLocation:) forControlEvents:UIControlEventTouchUpInside];<br />&nbsp; &nbsp; [self.view addSubview:buttonLaunchReverseGeocode];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; //Declaration de la roue qui indique une activité<br />&nbsp; &nbsp; activityReverseGeoCod =[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];<br />&nbsp; &nbsp; activityReverseGeoCod.hidesWhenStopped=YES;<br />&nbsp; &nbsp; activityReverseGeoCod.center=CGPointMake(260, 430);<br />&nbsp; &nbsp; [self.view addSubview:activityReverseGeoCod];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; //[b]Création du tableau d&#039;annotations[/b] !!!!!<br />&nbsp; &nbsp; arrayOfAnnotations=[[NSMutableArray alloc] initWithCapacity:4];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; MonAnnotation * annotationIut1=[[MonAnnotation alloc] init];<br />&nbsp; &nbsp; annotationIut1.title=@&quot;Lieu1&quot;;<br />&nbsp; &nbsp; annotationIut1.subtitle=@&quot;aaaaa&quot;;<br />&nbsp; &nbsp; annotationIut1.longitude=[NSNumber numberWithDouble:6.0+0.15226];<br />&nbsp; &nbsp; annotationIut1.latitude=[NSNumber numberWithDouble:48.0+0.66064];<br />&nbsp; &nbsp; annotationIut1.identifiant=[NSNumber numberWithInt:99999]; //Identifiant<br />&nbsp; &nbsp; [arrayOfAnnotations addObject:annotationIut1];<br />&nbsp; &nbsp; [annotationIut1 release];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; MonAnnotation * uneAnnotation1=[[MonAnnotation alloc] init];<br />&nbsp; &nbsp; uneAnnotation1.title=@&quot;Lieu2 &quot;;<br />&nbsp; &nbsp; uneAnnotation1.subtitle=@&quot;bbbbbb&quot;;<br />&nbsp; &nbsp; uneAnnotation1.longitude=[NSNumber numberWithDouble:4.0+0.15226];<br />&nbsp; &nbsp; uneAnnotation1.latitude=[NSNumber numberWithDouble:12.0+0.66064];<br />&nbsp; &nbsp; uneAnnotation1.identifiant=[NSNumber numberWithInt:1]; //Identifiant<br />&nbsp; &nbsp; [arrayOfAnnotations addObject:uneAnnotation1];<br />&nbsp; &nbsp; [uneAnnotation1 release];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; MonAnnotation *uneAnnotation2=[[MonAnnotation alloc] init];<br />&nbsp; &nbsp; uneAnnotation2.title=@&quot;Lieu3&quot;;<br />&nbsp; &nbsp; uneAnnotation2.subtitle=@&quot;ccccc&quot;;<br />&nbsp; &nbsp; uneAnnotation2.longitude=[NSNumber numberWithDouble:5.0+22.0/60.0];<br />&nbsp; &nbsp; uneAnnotation2.latitude=[NSNumber numberWithDouble:43.0+17.0/60.0];<br />&nbsp; &nbsp; uneAnnotation2.identifiant=[NSNumber numberWithInt:2]; //Identifiant<br />&nbsp; &nbsp; [arrayOfAnnotations addObject:uneAnnotation2];<br />&nbsp; &nbsp; [uneAnnotation2 release];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; MonAnnotation *uneAnnotation3=[[MonAnnotation alloc] init];<br />&nbsp; &nbsp; uneAnnotation3.title=@&quot;lieu4&quot;;<br />&nbsp; &nbsp; uneAnnotation3.subtitle=@&quot;dddd&quot;;<br />&nbsp; &nbsp; uneAnnotation3.longitude=[NSNumber numberWithDouble:8.0+22.0/60.0];<br />&nbsp; &nbsp; uneAnnotation3.latitude=[NSNumber numberWithDouble:40.0+17.0/60.0];<br />&nbsp; &nbsp; uneAnnotation3.identifiant=[NSNumber numberWithInt:88]; //Identifiant<br />&nbsp; &nbsp; [arrayOfAnnotations addObject:uneAnnotation3];<br />&nbsp; &nbsp; [uneAnnotation3 release];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; [maMapView addAnnotations:arrayOfAnnotations];<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; [super viewDidLoad];<br />}<br /><br /><br /><br />//Méthode position utilisateur, OK<br />-(void) reverseGeocodeCurrentLocation: (id) sender {.....}<br /><br /><br /><br />//zoom sur l&#039;utilisateur, OK <br />-(void) mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {...}<br /><br /><br /><br /><br />//Affiche l&#039;erreur en cas de probleme, OK<br />-(void) reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {....}<br /><br /><br />//OK<br />-(void) reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {... }<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br /><br /><br />//METHODE POUR PLACER UNE PUNAISE SUR LA CARTE, peut être ici le problème ?<br />-(MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id&lt;MKAnnotation&gt;)annotation {<br />&nbsp; &nbsp; //Si c&#039;est la position de l&#039;utilisateur, on laisse tel quel<br />&nbsp; &nbsp; if ([annotation isKindOfClass:[MKUserLocation class]]) {<br />&nbsp; &nbsp; &nbsp; &nbsp; return nil;<br />&nbsp; &nbsp; } <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; //On teste nos types d&#039;annotations<br />&nbsp; &nbsp; if ([annotation isKindOfClass:[MonAnnotation class]]) {<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; //On essaye de deplier une annotation view en premier<br />&nbsp; &nbsp; &nbsp; &nbsp; static NSString *MonAnnotationIdentifier=@&quot;monAnnotationIdentifier&quot;;<br />&nbsp; &nbsp; &nbsp; &nbsp; MKPinAnnotationView* pinView=(MKPinAnnotationView*)[maMapView dequeueReusableAnnotationViewWithIdentifier:MonAnnotationIdentifier];<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; if (!pinView) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MonAnnotation*myAnn=(MonAnnotation*)annotation; //Crée une annotation pour se servir de l&#039;identifiant<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Si il ,&#039;y en avait aucune de disponible, on en crée une tout simplement, on peut mm mettre une image (MonAnnotaionView)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MKPinAnnotationView* customPinView=[[[MKPinAnnotationView alloc] initWithAnnotation:myAnn reuseIdentifier:MonAnnotationIdentifier] autorelease];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customPinView.pinColor=MKPinAnnotationColorGreen;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customPinView.animatesDrop=YES;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customPinView.canShowCallout=YES;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //On ajoute une fleche pour ajouter plus d&#039;informations<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIButton* rightButton=[UIButton buttonWithType:UIButtonTypeDetailDisclosure];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rightButton.tag=[myAnn.identifiant integerValue];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customPinView.rightCalloutAccessoryView=rightButton;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;nom: %@ avec id : %@ avec un tag : %d &quot;,myAnn.title, myAnn.identifiant, rightButton.tag);<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [rightButton addTarget:self action:@selector(afficherLesDetails:) forControlEvents:UIControlEventTouchUpInside];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Ajout d&#039;une image a gauche<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIImageView *imageView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; imageView.image=[UIImage imageNamed:@&quot;annotationImage.png&quot;];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customPinView.leftCalloutAccessoryView=imageView;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [imageView release];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return customPinView;<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; else {<br />&nbsp; &nbsp; &nbsp; &nbsp; pinView.annotation=annotation;<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; return pinView;<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; return nil;<br />} <br /><br /><br />//SELECTOR DU BOUTON<br />-(void) afficherLesDetails: (id) sender&nbsp; {<br />&nbsp; &nbsp; UIButton*theButton=(UIButton*)sender;<br />&nbsp; &nbsp; NSLog(@&quot;La valeur de l&#039;ID est %@&quot;, theButton.tag);<br />&nbsp;  <br />}<br /><br /><br /><br /><br />- (void)dealloc<br />{<br />&nbsp; &nbsp; [arrayOfAnnotations release];<br />&nbsp; &nbsp; if(reverseGeocoder)<br />&nbsp; &nbsp; &nbsp; &nbsp; [reverseGeocoder release];<br />&nbsp; &nbsp; [maMapView release];<br />&nbsp; &nbsp; [activityReverseGeoCod release];<br />&nbsp; &nbsp; [labelReverseGeocoder release];<br />&nbsp; &nbsp; [buttonLaunchReverseGeocode release];<br />&nbsp; &nbsp; [super dealloc];<br />}<br /><br />@end<br /><br />




Je vois pas ou est mon erreur, si quelqu'un pourrait me venir en aide.
Merci.

Réponses

  • AliGatorAliGator Membre, Modérateur
    04:20 modifié #2
    J'ai pas lu tout le code, mais je parierai pour une mauvaise utilisation du mécanisme de recyclage/dequeue des MKAnnotation.

    Les MKAnnotations, tout comme les UITableViewCells dans une TableView, sont recyclées, pour éviter d'avoir trop d'allocations mémoires inutiles et prenant du temps. Du coup une MKAnnotation qui est utilisé pour un des POI peut être réutilisée plus tard pour un autre POI (surtout, typiquement, si tu scroll sur ta carte et qu'un POI qui était visible devient invisible / sort de la carte, et du coup la MKAnnotation associé sera réutilisée pour un POI qui lui vient d'apparaà®tre, etc)
    Sauf que si tu ne prends pas en compte ce mécanisme, tu vas créer une MKAnnotation, avec un tag, et puis plus tard elle va être réutilisée, mais si tu la réutilises telle quel sans changer le tag, c'est le tag de l'ancienne qui va être utilisé, etc...
  • AdamAdam Membre
    04:20 modifié #3
    Merci d'avoir répondu aussi rapidement.
    Si je comprend bien, mon problème pourrait provenir de cette ligne :
    <br />MKPinAnnotationView* pinView=(MKPinAnnotationView*)[maMapView dequeueReusableAnnotationViewWithIdentifier:MonAnnotationIdentifier];<br />
    


    C'est MonAnnotationIdentifier qui pose problème ? mais je ne vois pas par quoi le remplacer, vu que l'id doit être un NSString.
  • AliGatorAliGator Membre, Modérateur
    04:20 modifié #4
    Non ce n'est pas MonAnnotationIdentifier qui pose problème, c'est le fait qu'il faille comprendre, et prendre en compte surtout, que "dequeueReusableAnnotationView" peut te retourner une MKAnnotationView qui existe déjà , et qu'il "recycle". Exactement comme dequeueReusableCellWithIdentifier pour les UITableViews.

    Ainsi, imagine que tu as une carte sur laquelle tu veux positionner 10 POI en tout.
    Si ta carte est initialement un peu zoomée, au point que sur les 10 POI il n'y en a que disons 3 d'affichés, les 7 autres étant positionnés hors de la zone visible de la carte donc n'étant pas affichés à  l'écran.
    - Quand l'utilisateur va "scroller" pour déplacer la carte, un des 3 POI visibles va finir par disparaà®tre de la zone visible de la carte pour n'en laisser que deux. Au lieu de le détruire (et de le supprimer de la mémoire), iOS va alors le mettre de côté dans un "bac de recyclage".
    - Si l'utilisateur continue à  scroller, ou qu'il dézoome, et qu'un nouveau POI devient alors visible sur la carte, le code "dequeueReusableAnnotationViewWithIdentifier" va essayer de récupérer un MKAnnotationView du "bac de recyclage", plutôt que d'en créer un neuf avec un alloc+init. C'est ce que veux dire "dequeueReusable", il en récupère un existant (mais qui ne sert plus) pour le réutiliser. Cela permet d'éviter d'avoir à  en créer un neuf avec alloc+init et de le configurer (couleur du texte, vue personnalisée, bouton et son action dans la vue, etc... (car tout ça est un peu coûteux, pas tant que ça mais dans un contexte de "temps réel" où on scroll la carte rapidement et qu'on veut pas que le scroll "accroche" parce que le CPU va mettre 1/4s à  créer une nouvelle MKAnnotation, c'est important)
    - Or dans ton cas vu qu'on avait en effet une MKAnnotationView dans le "bac de recyclage", il va justement donc réutiliser cette MKAnnotation qui était avant utilisée par le POI qui a depuis disparu de la carte, cela lui évite d'en créer un nouveau. Donc "dequeueReusable..." va te retourner effectivement un MKAnnotation existant (non nil) qui avait été créé (et configuré) précédemment mais ne sert plus et donc va être recyclé
    - Si tu continues à  scroller ou dézoomer et qu'un 4e POI apparaà®t sur la carte, là  encore il va essayer de récupérer un MKAnnotationView du "bac de recyclage". Sauf que cette fois-ci il n'y en a plus, ils ont tous été recyclés et il n'y en a aucun qui traà®ne qui avait été créé avant mais ne sert plus. donc "dequeueReusable..." va te retourner "nil" car il ne va pas réussir à  en récupérer un "reusable", et du coup dans ce contexte il faut en créer un nouveau avec alloc+init+autorelease et le configurer.

    D'où la construction "if/else" qu'on doit respecter pour ce mécanisme de recyclage :
    <br />MKAnnotationView* v = [maMapView dequeueReusable...];<br />if (v == nil) {<br />&nbsp; // on n&#039;a pas réussi à  trouver une MKAnnotationView existante mais qui ne sert plus et qu&#039;on pourrait recycler<br />&nbsp; // du coup on est bien obligé d&#039;en créer une nouvelle<br />&nbsp; // ...<br />&nbsp; v = [[[MKAnnotationView alloc] initWithReuseIdentifier:...] autorelease];<br />&nbsp; // et ici on configure tout ce qui est &quot;statique&quot;, toutes les propriétés qui sont communes à  toutes les MKAnnotationViews<br />&nbsp; // genre ajout d&#039;une vue customisée ou d&#039;un bouton ou autre à  la MKAnnotationView<br />&nbsp; // ou changement de la couleur de la police utilisée, etc<br />&nbsp; // comme ça on n&#039;aura pas à  le faire à  chaque fois, puisque dans le cas où la MKAnnotationView est recyclée<br />&nbsp; // ces propriétés seront déjà  configurées<br />}<br />// Ici à  l&#039;extérieur du &quot;if&quot;, soit on a récupéré une MKAnnotationView recyclée via &quot;dequeueReusable...&quot; <br />// soit on est passé dans le &quot;if&quot; et on vient de la créer, mais dans les deux cas il faut quand même<br />// configurer toutes les propriétés qui elles sont propres à  chaque MKAnnotationView selon celle demandée<br />// par exemple le texte à  afficher sur ta MKAnnotationView, qui change d&#039;un POI à  l&#039;autre<br />// ou le tag associé, ou la NSURL vers laquelle mener quand on va cliquer sur la MKAnnotationView<br />// car tout cela n&#039;est pas commun à  tous les POI mais doit être changé si l&#039;annotation est une ancienne annotation recyclée
    
  • AdamAdam Membre
    04:20 modifié #5
    Okay, J'ai essayé de modifier la construction de mon programme.
    Maintenant cela me donne :

    <br /><br />//Methode pour placer une punaise sur la carte<br />-(MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id&lt;MKAnnotation&gt;)annotation {<br />&nbsp; &nbsp; //Si c&#039;est la position de l&#039;utilisateur, on laisse tel quel<br />&nbsp; &nbsp; if ([annotation isKindOfClass:[MKUserLocation class]]) {<br />&nbsp; &nbsp; &nbsp; &nbsp; return nil;<br />&nbsp; &nbsp; } <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; //On teste nos types d&#039;annotations<br />&nbsp; &nbsp; if ([annotation isKindOfClass:[MonAnnotation class]]) {<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; //On essaye de deplier une annotation view en premier<br />&nbsp; &nbsp; &nbsp; &nbsp; static NSString *MonAnnotationIdentifier=@&quot;monAnnotationIdentifier&quot;;<br />&nbsp; &nbsp; &nbsp; &nbsp; MKPinAnnotationView* pinView=(MKPinAnnotationView*)[maMapView dequeueReusableAnnotationViewWithIdentifier:MonAnnotationIdentifier];<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; if (pinView == nil) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MonAnnotation*myAnn=(MonAnnotation*)annotation; //Crée une annotation pour se servir de l&#039;identifiant<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Si il ,&#039;y en avait aucune de disponible, on en crée une tout simplement, on peut mm mettre une image (MonAnnotaionView)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MKPinAnnotationView* customPinView=[[[MKPinAnnotationView alloc] initWithAnnotation:myAnn reuseIdentifier:MonAnnotationIdentifier] autorelease];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customPinView.pinColor=MKPinAnnotationColorGreen;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customPinView.animatesDrop=YES;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customPinView.canShowCallout=YES;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //On ajoute une fleche pour ajouter plus d&#039;informations<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIButton* rightButton=[UIButton buttonWithType:UIButtonTypeDetailDisclosure];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rightButton.tag=[myAnn.identifiant integerValue];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customPinView.rightCalloutAccessoryView=rightButton;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;nom: %@ avec id : %@ avec un tag : %d &quot;,myAnn.title, myAnn.identifiant, rightButton.tag);<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [rightButton addTarget:self action:@selector(afficherLesDetails:) forControlEvents:UIControlEventTouchUpInside];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Ajout d&#039;une image a gauche<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIImageView *imageView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; imageView.image=[UIImage imageNamed:@&quot;annotationImage.png&quot;];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customPinView.leftCalloutAccessoryView=imageView;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [imageView release];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return customPinView;<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; pinView.annotation=annotation;<br />&nbsp; &nbsp; &nbsp; &nbsp; return pinView;<br /><br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return nil;<br />} <br />
    


    Mais j'ai toujours le même problème, peut-être ai-je mal compris une notion.
  • AliGatorAliGator Membre, Modérateur
    04:20 modifié #6
    Il faut que tout ce qui dépende de ta MKAnnotation soit à  l'extérieur du if !
    Bah oui, réfléchit, tout ce qui est commun à  tes MKAnnotationView genre le rajout du bouton ou l'image à  gauche, si c'est recyclé pour être utilisé pour une autre MKAnnotation, ça changera pas d'une MKAnnotation à  l'autre donc pas de souci tu mets ça dans le "if"...
    Mais vu que tes MKAnnotationViews sont recyclées pour être réutilisées pour d'autres MKAnnotations (POI), par contre tout ce qui dépend du POI (de la MKAnnotation) lui va devoir être ajusté.
    Ainsi si cette méthode est appellée, pour prévoir une MKAnnotationView pour une MKAnnotation donnée, il va sans doute recycler une MKAnnotationView existante, déjà  configurée avec une image à  gauche et un bouton à  droite, mais il faut quand même que tu réajustes ce qui est propre à  la MKAnnotation ! En particulier le tag de ton rightButton, dont tu te sers pour savoir où doit mener le clic !

    Il faut donc simplemebnt sortir de ton "if" tout ce qui est en rapport avec "myAnn", du [tt]MonAnnotation*myAnn=(MonAnnotation*)annotation;[/tt] à  toutes les lignes comme [tt]rightButton.tag = [myAnn.identifiant integerValue];[/tt] etc.

    Donc dans le "if" tu crées ton bouton pour le rightCalloutAccessoryView, car ce bouton n'a a être créé et rajouté qu'une fois, et il sera là  pour toutes les MKAnnotationViews
    Mais à  l'extérieur du "if", donc là  où tu mets le code qui de toute façon s'exécute pour toutes les MKAnnotations et donc le code qui dépend de la MKAnnotation et les trucs qui vont changer d'une MKAnnoationView à  l'autre, tu mets [tt]pinView.rightCalloutAccessoryView.tag = [myAnn.identifiant integerValue][/tt] comme ça le tag sera bien réajusté que la MKAnnotationView ait été recyclée/récupérée d'une ancienne MKAnnoationView existante mais ne servant plus, ou que tu viennes d'en alloc/init/autorelease une toute nouvelle.
  • AliGatorAliGator Membre, Modérateur
    04:20 modifié #7
    Ceci dit au fait :
    - pourquoi utiliser un NSNumber plutôt qu'utiliser un simple int, pourquoi se compliquer la vie ?
    - pourquoi ne pas utiliser [tt]- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control[/tt] plutôt que le @selector de ton UIButton ?
    - dans ton code tu utilises deux variables différentes selon si ton MKAnnotationView a été recyclée/retournée par "dequeueReusable..." (pinView) ou si ce dequeue n'a pas trouvé de cellule à  recycler et que tu crées du coup ta MKAnnotation from scratch avec alloc/init/autorelease (et dans ce cas tu utilises une autre variable, customPinView, alors qu'au final à  la fin du "if", que tu aies récupéré un objet MKAnnotationView existant que tu as recyclé d'une ancienne utilisation, ou que tu n'aies pas réussi à  trouver une MKAnnotationView à  recycler et que tu en crées une neuve, cela ne change rien au reste du code, après le "if" dans les 2 cas il faut terminer la customisation de ton MKAnnotationView en ajustant toutes les propriétés qui sont dépendantes de la MKAnnotation et qui changent d'une MKAnnotation à  l'autre.
  • AdamAdam Membre
    04:20 modifié #8
    J'ai commencé avec un NSNumber dans mon début de programme, et je m'en suis rendu compte après. Il faudra que je le modifie, c'est vrai que sa complique.

    Pour la méthode : - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control... Je ne connaissais pas, j'essayerai aussi de changer.


    Concernant le reste du code, je ne vois pas ce que l'on doit mettre après le if.  D'après ce que j'ai pu comprendre et lire, on met : pinView.annotation=annotation;
    Cela fonctionne mais le problème c'est que le triage se fait par ordre d'arrivé dans le viewForAnnotation: (ex: lieu3,lieu2,lieu1,lieu4).
    Donc j'aurai une inversion entre lieu 3 et lieu 1.
    Et je n'arrive pas à  remettre cette ordre.

    Désolé, je débute en programmation depuis quelques semaines, et j'ai encore quelques notions qui me reste abstraites.
  • AdamAdam Membre
    04:20 modifié #9
    Ahhh merci, sa y est ça marche.
    J'avais du mal à  comprendre qu'il fallait "recréer" certaines variable pour une pinView déjà  initialisée auparavant.
    maintenant apres le if, j'ai :

    <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MonAnnotation*myAnn=(MonAnnotation*)annotation;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIButton* rightButton=[UIButton buttonWithType:UIButtonTypeDetailDisclosure];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rightButton.tag = [myAnn.identifiant integerValue];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pinView.rightCalloutAccessoryView.tag = [myAnn.identifiant integerValue];<br />
    


    Et les Id sont bien reparties..
    Un grand merci, pour cette aide.
    Cela me permet enfin d'avancer dans mon programme 
Connectez-vous ou Inscrivez-vous pour répondre.