问题
Hey fellas, so I am able to display annotations (2) from the source code found at this link (and within the commented-out code post below).
However, I load annotation information from a plist and load it correctly (confirmed via debugger) into mapView but for some reason the annotations refuse to show when I run the app in the simulator. Here is the relevant code:
Annotation header:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface ArboretumAnnotation : NSObject <MKAnnotation> {
NSString *title;
NSString *subtitle;
UIImage *image;
CLLocationCoordinate2D coordinate;
}
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *subtitle;
@property (nonatomic, retain) UIImage *image;
@property (nonatomic) CLLocationCoordinate2D coordinate;
@end
Annotation implementation:
#import "ArboretumAnnotation.h"
@implementation ArboretumAnnotation
@synthesize title;
@synthesize subtitle;
@synthesize image;
@synthesize coordinate;
-(id)init{
self = [super init];
if(!self)
return nil;
self.title = nil;
self.subtitle = nil;
self.image = nil;
return self;
}
-(id)initWithCoordinate:(CLLocationCoordinate2D)inCoord{
self = [self init];
self.coordinate = inCoord;
return self;
}
@end
MapViewController header:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
@interface MapViewController : UIViewController <MKMapViewDelegate> {
MKMapView *mapView;
}
@property (nonatomic, retain) IBOutlet MKMapView *mapView;
- (void)showCurrentLocationButtonTapped:(id)sender;
- (void)loadAnnotations; //helper function that loads all overlay data from plist
- (void)loadOverlays; //helper function that loads all overlay data from plist
- (void)handleGesture:(UILongPressGestureRecognizer *)gestureRecognizer;
@end
MapViewController implementation:
#import "MapViewController.h"
#import "MKMapView+ZoomLevel.h"
#import "ArboretumRegionOverlay.h"
#import "ArboretumAnnotation.h"
#import "ArboretumAnnotationView.h"
#import "LocationDetailViewController.h"
#define UCD_LATITUDE 38.531728
#define UCD_LONGITUDE -121.755327
@implementation MapViewController
@synthesize mapView;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
//mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
mapView.delegate = self;
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Location Info" style:UIBarButtonItemStylePlain target:self action:nil];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:100 target:self action:@selector(showCurrentLocationButtonTapped:)];
[self loadAnnotations];
[self loadOverlays];
[mapView setNeedsDisplay];
/*
//TEST LOAD AN ANNOTATION
//MKPointAnnotation *testAnnot = [[MKPointAnnotation alloc] init];
ArboretumAnnotation *arboAnnot = [[ArboretumAnnotation alloc] init];
CLLocationCoordinate2D workingCoord;
workingCoord.latitude = 38.529977;
workingCoord.longitude = -121.76;
[arboAnnot setCoordinate:workingCoord];
[arboAnnot setTitle:@"Test Title"];
[arboAnnot setSubtitle:@"Test Subtitle"];
[mapView addAnnotation:arboAnnot];
[arboAnnot release];
ArboretumAnnotation *arboAnnot2 = [[ArboretumAnnotation alloc] init];
CLLocationCoordinate2D workingCoord2;
workingCoord2.latitude = 38.531594;
workingCoord2.longitude = -121.762129;
[arboAnnot2 setCoordinate:workingCoord2];
[arboAnnot2 setTitle:@"Test A really really really really long title Title2"];
[arboAnnot2 setSubtitle:@"Test A really really really really long sub Subtitle2"];
[mapView addAnnotation:arboAnnot2];
[arboAnnot2 release];
*/
//detects press gestures used for producing region overlay callout
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleGesture:)];
lpgr.minimumPressDuration = 0.3; //user must press for 1 second
//[mapView addGestureRecognizer:lpgr];
[lpgr release];
//initialize the map view (location and zoom)
CLLocationCoordinate2D centerCoord = { UCD_LATITUDE, UCD_LONGITUDE };
[mapView setCenterCoordinate:centerCoord zoomLevel:13 animated:NO];
}
- (void)showCurrentLocationButtonTapped:(id)sender {
NSLog(@"Showing current location.");
if ([mapView showsUserLocation] == NO) {
[mapView setShowsUserLocation:YES];
}
[mapView setCenterCoordinate:mapView.centerCoordinate zoomLevel:13 animated:YES];
}
- (void)loadAnnotations{
//retrieve path of plist file and populate relevant types with its information
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"ArboretumGardens" ofType:@"plist"];
NSDictionary *rootOfArboDataPlistDict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
NSMutableArray *arboAnnotations = [[NSMutableArray alloc] init];
for (NSString *key in rootOfArboDataPlistDict) {
NSMutableDictionary *arboDict = [rootOfArboDataPlistDict objectForKey:key];
//array containing annotation information: latitude, longitude, title, subtitle(see PermitData.plist)
NSArray *annotationsArray = [arboDict objectForKey:@"annotations"];
CLLocationCoordinate2D workingCoordinate;
//loop through annotations array, creating parking annotations filled with the information found in the plist
for(NSDictionary *annotationContainerDict in annotationsArray){
ArboretumAnnotation *arboAnnot = [[ArboretumAnnotation alloc] init];
workingCoordinate.latitude = [[annotationContainerDict objectForKey:@"latitude"] doubleValue];
workingCoordinate.longitude = [[annotationContainerDict objectForKey:@"longitude"] doubleValue];
[arboAnnot setCoordinate:workingCoordinate];
[arboAnnot setTitle:[annotationContainerDict objectForKey:@"title"]];
[arboAnnot setSubtitle:[annotationContainerDict objectForKey:@"subtitle"]];
[arboAnnotations addObject:arboAnnot];
[arboAnnot release];
}//for
}//for
[mapView addAnnotations:arboAnnotations];
[arboAnnotations release];
}
//...
- (ArboretumAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:MKUserLocation.class]) {
//it's the built-in user location annotation(blue dot)
return nil;
}
NSString *annotIdentifier = @"annotation";
MKPinAnnotationView *recycledAnnotationView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:annotIdentifier];
if (!recycledAnnotationView) {
MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:annotIdentifier] autorelease];
UIImage *iconImage = [UIImage imageNamed:@"arboretum.png"];
CGRect resizeRect;
resizeRect.size = iconImage.size;
CGSize maxSize = CGRectInset(self.view.bounds,
10.0f,
10.0f).size;
maxSize.height -= self.navigationController.navigationBar.frame.size.height + 40.0f;
if (resizeRect.size.width > maxSize.width)
resizeRect.size = CGSizeMake(maxSize.width, resizeRect.size.height / resizeRect.size.width * maxSize.width);
if (resizeRect.size.height > maxSize.height)
resizeRect.size = CGSizeMake(resizeRect.size.width / resizeRect.size.height * maxSize.height, maxSize.height);
customPinView.image = iconImage;
//customPinView.image.frame = CGRectMake(kBorder, kBorder, kWidth - 2 * kBorder, kWidth - 2 * kBorder);
customPinView.opaque = NO;
//customPinView.pinColor = MKPinAnnotationColorPurple;
customPinView.canShowCallout = YES;
//display a disclosure icon on the right side of each annotation's callout
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
customPinView.rightCalloutAccessoryView = rightButton;
return customPinView;
} else {
recycledAnnotationView.annotation = annotation;
}
return recycledAnnotationView;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
@end
Thanks in advance!
回答1:
Turns out the problem was in how I was retrieving coordinate data. I had swapped the longitude with the latitude inadvertently and the points wouldn't show at any point on the global map. No warnings or errors were issued by the compiler so it went unnoticed... So yeah, very embarrassing for me, but this is how you learn, right?
回答2:
I don't know if that is the problem but
isn't
self = [self init];
suppose to be
self = [super init];
来源:https://stackoverflow.com/questions/5268935/loading-annotations-to-map-view-from-plist-not-working