Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.0k views
in Technique[技术] by (71.8m points)

ios - custom annotation apple mapkit

I am trying to assign two custom annotations, one called "arsenal.png" and one called "chelsea.png"

Using apple mapkit framework, xcode 7.

Need assistance with code to achieve the customized markers.

here is my implementation file:

// TrucksViewController.m

#import "TrucksViewController.h"
#import "Annotation.h"

@interface TrucksViewController ()

@end

//Wimbledon Coordinates
#define WIMB_LATITUDE 51.434783;
#define WIMB_LONGITUDE -0.213428;

//Stadium Coordinates
#define ARSENAL_LATITUDE 51.556899;
#define ARSENAL_LONGITUDE -0.106483;

#define CHELSEA_LATITUDE 51.481314;
#define CHELSEA_LONGITUDE -0.190129;

//Span
#define THE_SPAN 0.20f;

@implementation TrucksViewController
@synthesize myMapView;

#pragma mark -
#pragma mark Initialisation

- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {

    self.title = @"Trucks";

    [[UIApplication sharedApplication] setStatusBarHidden:NO     withAnimation:UIStatusBarAnimationNone];
}
return self;
}

#pragma mark -
#pragma mark UIViewController Delegates

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
[super viewDidUnload];
}

-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

// Update support iOS 7
if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.navigationController.navigationBar.translucent = NO;
}
}

-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];

// Revert to default settings
if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {
    self.edgesForExtendedLayout = UIRectEdgeAll;
}
}

- (void)viewDidLoad 
{
[super viewDidLoad];

//Create Region
MKCoordinateRegion myRegion;

//Center
CLLocationCoordinate2D center;
center.latitude = ARSENAL_LATITUDE;
center.longitude = ARSENAL_LONGITUDE;

//Span
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;

//Region
myRegion.center = center;
myRegion.span = span;

//Set our mapview
[myMapView setRegion:myRegion animated:YES];

//Annotation
NSMutableArray * locations = [[NSMutableArray alloc] init];
CLLocationCoordinate2D location;
Annotation * myAnn;

//Arsenal annotation
myAnn = [[Annotation alloc] init];
location.latitude = ARSENAL_LATITUDE;
location.longitude = ARSENAL_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = @"Arsenal FC";
myAnn.subtitle = @"The Gunners";
[locations addObject:myAnn];

//Chelsea annotation
myAnn = [[Annotation alloc] init];
location.latitude = CHELSEA_LATITUDE;
location.longitude = CHELSEA_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = @"Chelsea FC";
myAnn.subtitle = @"The Blue Lions";
[locations addObject:myAnn];

[self.myMapView addAnnotations:locations];

}

@end

Additions posted 12/11/2013 18:31 hours Eastern

Updated Annotations.h file

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface Annotation : NSObject <MKAnnotation>

@property(nonatomic, assign) CLLocationCoordinate2D coordinate;
@property(nonatomic, copy) NSString * title;
@property(nonatomic, copy) NSString * subtitle;
@property(nonatomic, copy) NSString * imageName;

@end

Updated Annotations.m file

#import "Annotation.h"

@implementation Annotation
@synthesize coordinate, title, subtitle, imageName;

@end

Updated TrucksViewController.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>

@interface TrucksViewController : UIViewController {

}
@property (weak, nonatomic) IBOutlet MKMapView *myMapView;

@end

Updated TrucksViewController.m

(snip of code)

//Arsenal annotation
myAnn = [[Annotation alloc] init];
location.latitude = ARSENAL_LATITUDE;
location.longitude = ARSENAL_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = @"Arsenal FC";
myAnn.subtitle = @"The Gunners";
myAnn.imageName = @"arsenal";
[locations addObject:myAnn];

//Chelsea annotation
myAnn = [[Annotation alloc] init];
location.latitude = CHELSEA_LATITUDE;
location.longitude = CHELSEA_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = @"Chelsea FC";
myAnn.subtitle = @"The Blue Lions";
myAnn.imageName = @"chelsea";
[locations addObject:myAnn];

[self.myMapView addAnnotations:locations];

}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

Here is my updated TrucksViewController.m file: 12/11/2013 at 20:07 Eastern

// TrucksViewController.m

#import "TrucksViewController.h"
#import "Annotation.h"

@interface TrucksViewController ()


@end

//Wimbledon Coordinates
#define WIMB_LATITUDE 51.434783;
#define WIMB_LONGITUDE -0.213428;

//Stadium Coordinates
#define ARSENAL_LATITUDE 51.556899;
#define ARSENAL_LONGITUDE -0.106483;

#define CHELSEA_LATITUDE 51.481314;
#define CHELSEA_LONGITUDE -0.190129;

//Span
#define THE_SPAN 0.20f;

@implementation TrucksViewController
@synthesize myMapView;

//insert code per Anna

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:    (id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[Annotation class]])
{
    static NSString *reuseId = @"ann";
    MKAnnotationView *av = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
    if (av == nil)
    {
        av = [[MKAnnotationView alloc] initWithAnnotation:annotation     reuseIdentifier:reuseId];
    }
    else
    {
        av.annotation = annotation;
    }

    Annotation *ann = (Annotation *)annotation;
    av.image = [UIImage imageNamed:ann.imageName];

    return av;
}

//return nil (default view) if annotation is not our custom type
return nil;
}

//end new code per Anna

#pragma mark -
#pragma mark Initialisation

- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
    // Set the title for this view controller
    // Note: In future we will copy over the title from any created     UINavigationBar objects
    self.title = @"Trucks";

    [[UIApplication sharedApplication] setStatusBarHidden:NO         withAnimation:UIStatusBarAnimationNone];
}
return self;
}

#pragma mark -
#pragma mark UIViewController Delegates

- (void)viewDidUnload {
[super viewDidUnload];
}

-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

// Update support iOS 7
if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.navigationController.navigationBar.translucent = NO;
}
}

-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];

// Revert to default settings
if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {
    self.edgesForExtendedLayout = UIRectEdgeAll;
}
}

- (void)viewDidLoad
{
[super viewDidLoad];

//Create Region
MKCoordinateRegion myRegion;

//Center
CLLocationCoordinate2D center;
center.latitude = ARSENAL_LATITUDE;
center.longitude = ARSENAL_LONGITUDE;

//Span
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;

//Region
myRegion.center = center;
myRegion.span = span;

//Set our mapview
[myMapView setRegion:myRegion animated:YES];

//Annotation
NSMutableArray * locations = [[NSMutableArray alloc] init];
CLLocationCoordinate2D location;
Annotation * myAnn;

//Arsenal annotation
myAnn = [[Annotation alloc] init];
location.latitude = ARSENAL_LATITUDE;
location.longitude = ARSENAL_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = @"Arsenal FC";
myAnn.subtitle = @"The Gunners";
myAnn.imageName = @"arsenal.png";
[locations addObject:myAnn];

//Chelsea annotation
myAnn = [[Annotation alloc] init];
location.latitude = CHELSEA_LATITUDE;
location.longitude = CHELSEA_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = @"Chelsea FC";
myAnn.subtitle = @"The Blue Lions";
myAnn.imageName = @"chelsea.png";
[locations addObject:myAnn];

[self.myMapView addAnnotations:locations];

}

- (void)didReceiveMemoryWarning
   {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    }

@end
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You do need to implement the viewForAnnotation delegate method to show images for your annotations instead of the standard red pin.

In that delegate method, you need to create and return an MKAnnotationView with its image property set to the image you want for the annotation.

You will get a reference to the annotation the map view is asking for a view for and using the annotation's properties, you set the image accordingly.

You could base it on the annotation's title value but I'd suggest the following approach instead:

  1. Add a imageName property of type NSString to your Annotation class. Set this property to the image name to use for the annotation before you call addAnnotation on it. For example:

    myAnn.title = @"Arsenal FC";
    myAnn.subtitle = @"The Gunners";
    myAnn.imageName = @"arsenal";
    [locations addObject:myAnn];
    
  2. In the viewForAnnotation delegate method, check if the annotation is of type Annotation and then use its imageName property to set the annotation view's image property:

    -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
    {
        if ([annotation isKindOfClass:[Annotation class]])
        {
            static NSString *reuseId = @"ann";
            MKAnnotationView *av = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
            if (av == nil)
            {
                av = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
            }
            else
            {
                av.annotation = annotation;
            }
    
            Annotation *ann = (Annotation *)annotation;
            av.image = [UIImage imageNamed:ann.imageName];
    
            return av;
        }
    
        //return nil (default view) if annotation is not our custom type
        return nil;
    }
    

Also, don't forget to set the map view's delegate property otherwise the delegate method won't get called. In Interface Builder, connect the delegate outlet to the view controller.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...