Reputation: 2475
I'd like to set an image to MKAnnotationView.
But the image is not reflected. It is normal red pin.
ViewController.m
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "CustomAnnotation.h"
@interface ViewController ()<MKMapViewDelegate>
@end
@implementation ViewController{
MKMapView* _mapView;
}
- (void)viewDidLoad{
CustomAnnotation* annotation = [[CustomAnnotation alloc]init];
annotation.coordinate = CLLocationCoordinate2DMake(35.6699877, 139.7000456);
annotation.image = [UIImage imageNamed:@"annotation.png"];
[_mapView addAnnotations:@[annotation]];
}
CustomAnnotation.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
@interface CustomAnnotation : MKAnnotationView
@property (readwrite, nonatomic) CLLocationCoordinate2D coordinate;
@property (readwrite, nonatomic, strong) NSString* title;
@end
CustomAnnotation.m
#import "CustomAnnotation.h"
@implementation CustomAnnotation
@end
Upvotes: 0
Views: 71
Reputation:
To use a custom image, you have to create and return an MKAnnotationView
in the map view's viewForAnnotation
delegate method.
If you don't implement that delegate method, the map view will display a default red pin for the annotations you add (regardless of what class the annotations are).
Here's an example of how you could implement it:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if (! [annotation isKindOfClass:[CustomAnnotation class]])
{
//if this annotation is not a CustomAnnotation
//(eg. user location blue dot),
//return nil so the map view draws its default view for it...
return nil;
}
static NSString *reuseId = @"ann";
MKAnnotationView *av = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (av == nil)
{
av = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
av.canShowCallout = YES;
av.image = [UIImage imageNamed:@"annotation.png"];
}
else
{
av.annotation = annotation;
}
return av;
}
Be sure to set the map view's delegate
property either in code or connect the outlet in the storyboard/xib. If the delegate
is not set, the map view won't call the viewForAnnotation
method even if you've implemented it and you'll still get the default red pin.
The addAnnotation
and addAnnotations
methods are only asking for the annotation model objects (objects that implement the MKAnnotation
protocol which mainly consists of the coordinate
property).
The views for those annotation model objects must be returned in the viewForAnnotation
delegate method.
Even though your CustomAnnotation
class doesn't explicitly declare that it conforms to MKAnnotation
, it implements a coordinate
property, so the map view is able to show it on the map.
The fact that it happens to also be a subclass of MKAnnotationView
is something the map view doesn't care about or use from the annotation model object.
Your annotation model object should not be a subclass of MKAnnotationView
as it will just lead to confusion. It should just implement the MKAnnotation
protocol so it should be a subclass of NSObject<MKAnnotation>
(or some other custom class besides NSObject
).
Change the CustomAnnotation
interface to:
@interface CustomAnnotation : NSObject<MKAnnotation>
Change the title
property from strong
to copy
to match the MKAnnotation
protocol:
@property (readwrite, nonatomic, copy) NSString* title;
Since CustomAnnotation
is no longer an MKAnnotationView
, remove the image =
line from viewDidLoad
and be sure to set the annotation's title
otherwise the callout won't show when you tap on it:
//annotation.image = [UIImage imageNamed:@"annotation.png"];
annotation.title = @"annotation";
Upvotes: 1