从 Plist 加载注释到地图视图不起作用

发布于 2024-10-21 12:54:22 字数 8750 浏览 2 评论 0原文

嘿伙计们,所以我可以从找到的源代码中显示注释(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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

就像说晚安 2024-10-28 12:54:22

事实证明,问题出在我检索坐标数据的方式上。我无意中交换了经度和纬度,这些点不会在全球地图上的任何点显示。编译器没有发出警告或错误,所以它没有被注意到......所以是的,对我来说非常尴尬,但这就是你学习的方式,对吗?

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?

时光磨忆 2024-10-28 12:54:22

我不知道这是否是问题所在,但

不应该

 self = [self init];

是问题

self = [super init];

I don't know if that is the problem but

isn't

 self = [self init];

suppose to be

self = [super init];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文