0

as the title describes i am having trouble displaying the data that i have in my plist for annotations in the map view project i am working on using segue in storyboard. i have the map view and all the annotations (pins) are showing their co ordinates properly. now i want to use segue to transition into a detail view when the user has pressed the detail disclosure button. so far i have the following which is an empty perform segue:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
[self performSegueWithIdentifier:@"Details" sender:view];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
}

the details i want to display in detail view are declared as strings. as follows

@interface ItalyMapDetail : UIViewController{
IBOutlet UIImageView *appImage;
IBOutlet UITextView *appText;
IBOutlet UILabel *appName;

NSString *appImageString;
NSString *appTextString;
NSString *appNameString;

}

@property (nonatomic, retain) NSString *appImageString;
@property (nonatomic, retain) NSString *appTextString;
@property (nonatomic, retain) NSString *appNameString;
@property (nonatomic, strong) UIImage* image;

@end

and in .m file it is as follows

@synthesize appImageString, appTextString, appNameString;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

appImage.image = [UIImage imageNamed:appImageString];
appText.text = appTextString;
appName.text = appNameString;
}

which is truly generic declaration of some strings in detail view. the segue identifier fires and the view transitions to detail view and back properly since i have a navigation controller already. now i know how to declare the strings in prepare for segue when it comes to tableview but i don't know how to declare these details from my plist in the segue in order to display the annotation details in the detail view controller. can anyone give me a hand with this.

oh by the way here is the decleration of the annotations which i derive from plist in my view did load if that helps.

NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSString *path = [[NSBundle mainBundle] pathForResource:@"Map" ofType:@"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSArray *anns = [dict objectForKey:@"Italy"];

for(int i = 0; i < [anns count]; i++) {
    float realLatitude = [[[anns objectAtIndex:i] objectForKey:@"Latitude"] floatValue];
    float realLongitude = [[[anns objectAtIndex:i] objectForKey:@"Longitude"] floatValue];

    Annotation *myAnnotation = [[Annotation alloc] init];
    CLLocationCoordinate2D theCoordinate;
    theCoordinate.latitude = realLatitude;
    theCoordinate.longitude = realLongitude;
    myAnnotation.coordinate = theCoordinate;
    myAnnotation.title = [[anns objectAtIndex:i] objectForKey:@"Title"];
    myAnnotation.subtitle = [[anns objectAtIndex:i] objectForKey:@"Subtitle"];
    [myMapView addAnnotation:myAnnotation];
    [annotations addObject:myAnnotation];
}

i know this might be very easy for most of you guys out there but i am truly stuck and i can use some help in code level.

Edit 1:

here is the code after the changes suggested :

    NSMutableArray *annotations = [[NSMutableArray alloc]init];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"ItalyMap" ofType:@"plist"];
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
    NSArray *anns = [dict objectForKey:@"Italy"];

    for(int i = 0; i < [anns count]; i++) {
    float realLatitude = [[[anns objectAtIndex:i] objectForKey:@"Latitude"] floatValue];
    float realLongitude = [[[anns objectAtIndex:i] objectForKey:@"Longitude"] floatValue];

    Annotation *myAnnotation = [[Annotation alloc] init];
    CLLocationCoordinate2D theCoordinate;
    theCoordinate.latitude = realLatitude;
    theCoordinate.longitude = realLongitude;
    myAnnotation.coordinate = theCoordinate;
    myAnnotation.title = [[anns objectAtIndex:i] objectForKey:@"Title"];
    myAnnotation.subtitle = [[anns objectAtIndex:i] objectForKey:@"Subtitle"];
    [myMapView addAnnotation:myAnnotation];
    [annotations addObject:myAnnotation];

    myAnnotation.annotationData = [anns objectAtIndex:i];
}

}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(@"view for annotation works");

if([annotation isKindOfClass:[MKUserLocation class]])
    return nil;

static NSString *annotationIdentifier = @"AnnotationIdentifier";

MKPinAnnotationView *pinView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];

if (!pinView)
{
    pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];

    [pinView setPinColor:MKPinAnnotationColorGreen];
    pinView.animatesDrop = YES;
    pinView.canShowCallout = YES;

    UIImageView *iconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"acolon1.png"]];
    pinView.leftCalloutAccessoryView = iconView;

    pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
else
{
    pinView.annotation = annotation;
}

return pinView;
}

-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
// Keep a reference to the callout's annotation data
self.selectedAnnotationData = [(Annotation *)view.annotation annotationData];

[self performSegueWithIdentifier:@"Details" sender:self];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"Details"])
{
    ItalyMapDetail *controller = segue.destinationViewController;
    controller.annotationData = self.selectedAnnotationData;
}
}

now i have added the dic to the annotation and detail view is imported. the only thing that is not showing still is the strings and the image in the detail view.

Adrian P
  • 6,479
  • 4
  • 38
  • 55

1 Answers1

1

You could pass the particular data object to the Annotation using

myAnnotation.annotationData = [anns objectAtIndex:i];

Then in prepareForSegue:sender: you could access the annotation data and pass it to the detail view controller.


Edit: Added sample code

Declare a property on the Annotation class:

@property (nonatomic, strong) NSDictionary *annotationData;

Declare a property on the same view controller as your map view:

@property (nonatomic, strong) NSDictionary *selectedAnnotationData;

And implement the map view delegate method:

-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
    // Keep a reference to the callout's annotation data
    self.selectedAnnotationData = [(Annotation *)view.annotation annotationData];

    [self performSegueWithIdentifier:@"MY_SEGUE_IDENTIFIER" sender:self];
}

Then pass the annotation data to the subsequent controller in the prepareForSegue:sender: method:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"showPlattegrondDetails"])
    {
        ItalyMapDetail *controller = segue.destinationViewController;
        controller.annotationData = self.selectedAnnotationData;
    }
}

Edit 2: Based on edited question.

Without knowing the names of the keys in the plist, I can only point you in the direction you should be looking.

Your ItalyMapDetail controller should have the annotation data dictionary as provided in prepareForSegue:sender: of the previous controller, it should just be a case of using values from that dictionary to populate your UI...

Update your viewDidLoad method of the ItalyMapDetail controller as follows:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // temporary test: print out the annotation data so
    // we can see what we've got. This shouldn't be nil.
    NSLog("Annotation Data: %@", self.annotationData);

    // replace these keys with appropriate ones for your plist
    appImage.image = [UIImage imageNamed:self.annotationData[@"imageName"]];
    appText.text = self.annotationData[@"appText"];
    appName.text = self.annotationData[@"appName"];
}
Steve Wilford
  • 8,894
  • 5
  • 42
  • 66
  • You'll need to declare an NSDictionary @property called `annotationData` on your `Annotation` class. Sorry, I didn't include this in my sample :( – Steve Wilford Sep 05 '13 at 16:30
  • The original version of my answer suggested you pass the entire dictionary for the current annotation into the annotation. `myAnnotation.annotationData = [anns objectAtIndex:i];`. This would be done within the for loop where you setup each annotation as shown in your final code snippet in the question. – Steve Wilford Sep 05 '13 at 18:54
  • Can you update your question with more code from your latest attempt? I'm struggling to see where the problem might be. – Steve Wilford Sep 06 '13 at 12:59
  • just updated the codes with inclusion of your suggested codes. – Adrian P Sep 06 '13 at 13:15
  • steve, you are a great help and i thank you thank you and thank you for saving my head from exploding. i cant believe i was missing the whole structure of detail view. i am grateful for your help and not just rewarding with the right answer also up voting your answer as well my friend. thank you so much...:) – Adrian P Sep 06 '13 at 13:47