2010-12-08 43 views
3

J'ai une vue de la carte avec des broches que lorsque l'utilisateur sélectionne une broche, il va à un écran de détail pour cette broche. J'ai également une vue de table qui quand l'utilisateur sélectionne un article il va à la vue de détail de même type.Problème avec l'annotation de carte et MKMapView dans iOS 4.2?

est ici le problème ...

Il semble fonctionner très bien dans tout de 3.1.3 à 4.1. C'est la vue de détail correspond à la broche. Mais j'ai un utilisateur qui vient de mettre à niveau vers iOS 4.2 et dit que sous 4.1 cela a bien fonctionné, mais en 4.2, la sélection des broches le prend au détail pour une broche différente. Mais dans la vue de la table cela fonctionne toujours bien.

Est-il possible qu'il y ait eu un changement dans MKMapView dans iOS 4.2 qui change la façon dont le pinID est sélectionné?

Addition - J'ai ajouté les parties pertinentes de viewForAnnotation et checkButtonTapped

- (MKPinAnnotationView *)mapView:(MKMapView *)eMapView viewForAnnotation:(id <MKAnnotation>)annotation { 

int postTag = 0; 

MKPinAnnotationView *pinView = (MKPinAnnotationView *)[eMapView dequeueReusableAnnotationViewWithIdentifier:@"Pin"]; 

if(pinView == nil) { 

    pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Pin"]; 
    pinView.frame = CGRectMake(0, 0, 25, 25); 

} else { 

    pinView.annotation = annotation; 

} 

// Set up the Right callout 
UIButton *myDetailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
myDetailButton.frame = CGRectMake(0, 0, 23, 23); 
myDetailButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; 
myDetailButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; 

[myDetailButton addTarget:self action:@selector(checkButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; 

// Identify which pin is being selected 
if ([[annotation title] isEqualToString:@"Current Location"]) { 
    postTag = 99999; 
} else { 
    postTag = [annotation getPinID]; 

} 

myDetailButton.tag = postTag; 

pinView.rightCalloutAccessoryView = myDetailButton; 

pinView.animatesDrop = YES; 

// Set to show a callout on the pin 
pinView.canShowCallout = YES; 

return pinView; 
} 

// Method to show detail view when the callOut button is selected 
- (IBAction) checkButtonTapped: (id) sender { 

int nrButtonPressed = ((UIButton *)sender).tag; 

if (nrButtonPressed < 99999) { 
    if (self.showDetailView == nil) { 

     DetailData *tmpViewController = [[DetailData alloc] initWithNibName:@"Detail" bundle:nil]; 
     self.showDetailView = tmpViewController; 
     [tmpViewController release]; 

    } 

    buttonDetail = [[mapView annotations] objectAtIndex:(nrButtonPressed-1)]; 

    NSMutableArray *tmpArray = [NSMutableArray arrayWithObjects: [buttonDetail getDataI], [buttonDetail getDataII], [buttonDetail getDataIII], [buttonDetail getDataIV], [buttonDetail getDataV], nil]; 

    self.showDetailView.eventData = [[NSMutableArray alloc] initWithArray:tmpArray copyItems:YES]; 

    [self.navigationController pushViewController:self.showDetailView animated:YES]; 

    [self.showDetailView.eventData release]; 

} 

}

Comme vous pouvez le voir, checkButtonTapped j'enregistre la broche sélectionnée puis recueillir les données de l'annotation pour que la broche . Le problème semble être que nrButtonPressed est maintenant incorrect. Mais il est correct lorsqu'il est compilé dans 4.1

+0

Affiche la méthode viewForAnnotation et le code qui gère la sélection des broches. – Anna

+0

Je serai heureux de poster le code (c'est juste assez long) mais je ne pense pas que ce soit le problème. La raison en est que je cours une version compilée en 4.1 sur un iPod Touch et c'est bien.Je n'ai fait aucun changement à viewForAnnotation et quand j'ai compilé en 4.2 il a l'erreur dans le simulateur (émulation de l'iPhone 4.2) L'utilisateur a dit qu'une ancienne version de l'application fonctionnait bien dans 4.1, mais quand il a mis à jour 4.2 de l'application a commencé à montrer l'erreur. Voulez-vous toujours le code parce que je vais le poster si vous le faites? – LancDec

+0

Si le code est très long et complexe, vous devrez effectuer un débogage et isoler la zone de problème possible. Essayez de reproduire le problème dans un petit projet distinct. La seule différence dans 4.2 MapKit notée dans les [Release Notes] d'Apple (https://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-4_2/index.html) concerne le traitement de la vue d'annotation. use (Voir l'entrée MapKit sous Notes et problèmes connus). Cela peut être pertinent pour vous. – Anna

Répondre

4

Dans checkButtonTapped, l'annotation est identifiée à l'aide de la balise du bouton. La balise du bouton est définie dans viewForAnnotation en appelant la méthode personnalisée getPinID.

La balise de bouton est utilisée comme index dans le tableau d'annotations mapView. Il n'est pas clair comment la méthode getPinID détermine à quel index elle se trouve dans le tableau d'annotations de mapView. Je ne suis pas sûr qu'il est sage de supposer qu'une annotation va être à un index spécifique dans le tableau. Même si mapView ne mélange pas les annotations, il se peut que votre application ajoute et supprime constamment des annotations. Etant donné que vous affectez le bouton en tant qu'accessoire de légende dans la vue d'annotation, plutôt que d'utiliser une étiquette de bouton pour identifier l'annotation, vous pouvez utiliser la méthode de délégation mapView:annotationView:calloutAccessoryControlTapped: de mapView. Au lieu de faire addTarget sur le bouton et de l'appeler par votre méthode personnalisée, supprimez l'appel à addTarget et implémentez calloutAccessoryControlTapped.

Dans calloutAccessoryControlTapped, vous pouvez accéder directement à l'annotation à l'aide de view.annotation. Vous pouvez également facilement vérifier si l'annotation est le « emplacement de l'utilisateur »:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 
    { 
     if (view.annotation == mapView.userLocation) 
      return; 

     buttonDetail = (MyCustomAnnotationClass *)view.annotation; 

     //show detail view using buttonDetail... 
    } 

De plus, dans viewForAnnotation, vous créez un bouton à chaque fois, même si la vue est réutilisée. Ainsi, une vue d'annotation réutilisée finit probablement par avoir plusieurs boutons les uns sur les autres. Le bouton doit uniquement être créé et défini dans la section if(pinView == nil).

+0

Merci beaucoup. J'ai fait le changement en utilisant calloutAccessoryControlTapped et maintenant cela fonctionne. J'ai fait une petite addition qui semble maintenant évidente mais il n'y a pas une heure. Dans la méthode calloutAccessoryControlTapped, j'ai besoin d'ajouter initWithNibName avant le boutonDetail. – LancDec

0

Si quelqu'un veut bien voir ce que je suis maintenant en utilisant (et travaille) ...

- (MKPinAnnotationView *)mapView:(MKMapView *)eMapView viewForAnnotation:(id <MKAnnotation>)annotation { 

    MKPinAnnotationView *pinView = (MKPinAnnotationView *)[eMapView dequeueReusableAnnotationViewWithIdentifier:@"Pin"]; 

    if(pinView == nil) { 

     pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Pin"]; 
     pinView.frame = CGRectMake(0, 0, 25, 25); 

    } else { 

     pinView.annotation = annotation; 

    } 

    // Set up the Right callout 
    UIButton *myDetailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
    myDetailButton.frame = CGRectMake(0, 0, 23, 23); 
    myDetailButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; 
    myDetailButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; 

    pinView.rightCalloutAccessoryView = myDetailButton; 

    pinView.animatesDrop = YES; 

    // Set to show a callout on the pin 
    pinView.canShowCallout = YES; 

    return pinView; 
} 

// Added this at the suggestion of aBitObvious on StackOverflow - 120810 
- (void)mapView:(MKMapView *)eMapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { 

    if (view.annotation == eMapView.userLocation) 
     return; 

    if (self.showDetailView == nil) { 

     DetailData *tmpViewController = [[DetailData alloc] initWithNibName:@"DetailData" bundle:nil]; 
     self.showDetailView = tmpViewController; 
     [tmpViewController release]; 

    } 

    buttonDetail = (MyCustomAnnotationClass *)view.annotation; 

    NSMutableArray *tmpArray = [NSMutableArray arrayWithObjects: [buttonDetail getDataI], [buttonDetail getDataII], [buttonDetail getDataIII], [buttonDetail getDataIV], [buttonDetail getDataV], nil]; 

    self.showDetailView.eventData = [[NSMutableArray alloc] initWithArray:tmpArray copyItems:YES]; 

    [self.navigationController pushViewController:self.showDetailView animated:YES]; 

    [self.showDetailView.eventData release]; 

} 

Merci encore!