I’m working on an iPhone application that displays a list of galleries on a Map. The list of galleries comes from a plist which is downloaded from the web. The location coordinates are loading into the map correctly as well as the title and subtitle for each of the locations.
I am also able to load an image for the annotation view image from the plist.
The issue I’m having is that both the annotation view image and a detail view page load the information of the last location in the plist array rather than loading the information that corresponds to the correct location information.
I believe that the problem has to do with this integer:
for(int i=0; i < [galleries count]; i++)
but I’m honestly not sure.
Any help would be greatly appreciated!
Here is the code:
MapAnnotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MKAnnotation.h>
@interface MapAnnotation : NSObject <MKAnnotation>{
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subTitle;
}
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@end
MapAnnotation.m
#import "MapAnnotation.h"
@implementation MapAnnotation
@synthesize coordinate, title, subtitle;
@end
MapViewViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
@interface MapViewViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>{
NSMutableArray *galleries;
MKMapView *_MapView;
MKAnnotationView *Ann;
}
@property (nonatomic, retain) IBOutlet MKMapView *_MapView;
@property (nonatomic, retain) IBOutlet MKAnnotationView *Ann;
@property (nonatomic, retain) NSArray *addressArray;
@property (nonatomic, retain) NSMutableArray *galleries;
@property (nonatomic, retain) NSString *imageUrl;
@property (nonatomic, retain) NSData *imagedata;
-(IBAction)getlocation;
- (void)loadAnnotations;
@end
MapViewViewController.m
#import "MapViewViewController.h"
#import "MapAnnotation.h"
#import "MoredetailViewController.h"
@implementation MapViewViewController
@synthesize _MapView, Ann;
@synthesize galleries, addressArray;
@synthesize imagedata, imageUrl;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[galleries removeAllObjects];
addressArray=[[NSMutableArray alloc]initWithContentsOfURL:[NSURL URLWithString:@"http://www.jimirobinson.com/plist/MapInformation.plist"]];
galleries = [[NSMutableArray alloc] initWithArray:addressArray];
[self loadAnnotations];
}
- (void)viewDidLoad
{
[super viewDidLoad];
MKCoordinateRegion region;
region.center.latitude = 39.952133;
region.center.longitude = -75.144264;
region.span.longitudeDelta = 0.005;
region.span.latitudeDelta = 0.001;
[_MapView setRegion:region animated:YES];
}
-(IBAction)getlocation {
_MapView.showsUserLocation = YES;
}
- (void)loadAnnotations {
CLLocationCoordinate2D pinCoordinates;
for (int i = 0; i < [galleries count]; i++)
{
MapAnnotation *myAnnotations = [[MapAnnotation alloc] init];
pinCoordinates.latitude = [[[galleries objectAtIndex:i] objectForKey:@"latitude"] floatValue];
pinCoordinates.longitude = [[[galleries objectAtIndex:i] objectForKey:@"longitude"] floatValue];
[myAnnotations setTitle:[[galleries objectAtIndex:i] objectForKey:@"annotation_title"]];
[myAnnotations setSubtitle:[[galleries objectAtIndex:i] objectForKey:@"annotation_subtitle"]];
imageUrl = [[galleries objectAtIndex:i] objectForKey:@"map_pin_image_url"];
imagedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
[myAnnotations setCoordinate:pinCoordinates];
[_MapView addAnnotation:myAnnotations];
}
}
- (MKAnnotationView *)mapView :(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"AddrAnnot"];
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"AddrAnnot"];
if (_MapView.userLocation == annotation)
{
return nil;
}
annotationView.image = [UIImage imageWithData:imagedata];
annotationView.canShowCallout = YES;
[annotationView setBackgroundColor:[UIColor clearColor]];
[annotationView setFrame:CGRectMake(0, 0, 30, 30)];
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annotationView.leftCalloutAccessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"flag1.png"]];
[_MapView addAnnotation:annotation];
return annotationView;
NSLog(@"%s: annotationView=%@", __func__, annotationView);
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
MoredetailViewController *moredetail = [self.storyboard instantiateViewControllerWithIdentifier:@"TextPage"];
[self.navigationController pushViewController:moredetail animated:YES];
for(int i=0; i < [galleries count]; i++)
{
moredetail.MoredetailTitle.text = [[galleries objectAtIndex:i] objectForKey:@"annotation_title"];
moredetail.MoredetailDescription.text = [[galleries objectAtIndex:i] objectForKey:@"annotation_subtitle"];
NSLog(@"%d", i);
NSString *image = [[galleries objectAtIndex:i] objectForKey:@"map_pin_image_url"];
NSData *dataz = [NSData dataWithContentsOfURL:[NSURL URLWithString:image]];
moredetail.detailImage.image = [UIImage imageWithData:dataz];
}
NSLog(@"I've been tapped");
}
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
NSLog(@"%s: galleries=%@", __func__, galleries);
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
@end
MapInformation.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>title</key>
<string>Gallery One</string>
<key>annotation_title</key>
<string>Gallery One Title</string>
<key>annotation_subtitle</key>
<string>Gallery One Subtitle</string>
<key>map_pin_image_url</key>
<string>http://www.jimirobinson.com/plist/flag1.png</string>
<key>latitude</key>
<real>39.952827</real>
<key>longitude</key>
<real>-75.145203</real>
</dict>
<dict>
<key>title</key>
<string>Gallery Two</string>
<key>annotation_title</key>
<string>Gallery Two Title</string>
<key>annotation_subtitle</key>
<string>Gallery Two Subtitle</string>
<key>map_pin_image_url</key>
<string>http://www.jimirobinson.com/plist/flag2.png</string>
<key>latitude</key>
<real>39.952184</real>
<key>longitude</key>
<real>-75.145368</real>
</dict>
<dict>
<key>title</key>
<string>Gallery Three</string>
<key>annotation_title</key>
<string>Gallery Three Title</string>
<key>annotation_subtitle</key>
<string>Gallery Three Subtitle</string>
<key>map_pin_image_url</key>
<string>http://www.jimirobinson.com/plist/flag3.png</string>
<key>latitude</key>
<real>39.951135</real>
<key>longitude</key>
<real>-75.143368</real>
</dict>
</array>
</plist>
I’m afraid to say but this code needs lots of work in order to work as you expect.
Firstly,
imagedatais an instance variable, and you are setting it to be the image data of the last annotation (inloadAnnotations).viewForAnnotationthen usesimagedatafor the image, so it will always be set to the image for the last annotation.Secondly, in
calloutAccessoryControlTappedyou are iterating over all the galleries, and setting properties on themoredetailview controller, so that the view controller will always show detail for the last gallery.I suggest that you add more properties to your
MapAnnotationclass, such as imageUrl. You can then set this property when creating the annotations. InviewForAnnotationyou can then do this:And in the
calloutAccessoryControlTappedmethod you can do this:I hope this gives you some idea of how to get your code working.