从 Plist 加载注释到地图视图不起作用
嘿伙计们,所以我可以从找到的源代码中显示注释(2)
但是,我从 plist 加载注释信息并将其正确加载(通过调试器确认)到 mapView 中,但由于某种原因,当我在模拟器中运行应用程序时,注释拒绝显示。这是相关代码:
注释标头:
#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
注释实现:
#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 标头:
#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 实现:
#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
提前致谢!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
事实证明,问题出在我检索坐标数据的方式上。我无意中交换了经度和纬度,这些点不会在全球地图上的任何点显示。编译器没有发出警告或错误,所以它没有被注意到......所以是的,对我来说非常尴尬,但这就是你学习的方式,对吗?
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?
我不知道这是否是问题所在,但
不应该
是问题
I don't know if that is the problem but
isn't
suppose to be