1

I am trying to change the standard pin to my own image but I keep failing after several attempts.

I have tried different codes and guides that I have found here in this forum but none of them seems to work. I belive I am pasting the code in to my project wrongly. Any ideas how to replace the regular pin with my own image?

//.h

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

@interface MapPin : NSObject <MKAnnotation> {

    CLLocationCoordinate2D coordinate;
    NSString *title;
    NSString *subtitle;
}

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

- (id)initWithLocation:(CLLocationCoordinate2D)coord;

@end

//.m

#import <Foundation/Foundation.h>
#import "MapPin.h"

@implementation MapPin

@synthesize coordinate,title,subtitle;

- (id)initWithLocation:(CLLocationCoordinate2D)coord{

    self = [super init];
    if (self) {
        coordinate = coord;
    }
    return self;
}
@end

//Viewcontroller.h

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

@interface FirstViewController : UIViewController <UIAlertViewDelegate, UIWebViewDelegate> {

    MKMapView *mapview;

}
- (IBAction)information;
@property (strong, nonatomic) IBOutlet UIScrollView *ScrollView;
@property (strong, nonatomic) IBOutlet UIImageView *image;
@property (retain, nonatomic) IBOutlet MKMapView *mapview;

- (IBAction)showMenu;
- (IBAction)setMap:(id)sender;
- (IBAction)GetLocation:(id)sender;

@end

//Viewcontroller.m

#import "FirstViewController.h"
#import "MapPin.h"

@implementation FirstViewController

@synthesize ScrollView, image;
@synthesize mapview;

- (void)viewDidLoad{

    MKCoordinateRegion region = { {0.0, 0.0}, {0.0,0.0}};
    region.center.latitude = 55.709900;
    region.center.longitude = 13.201207;
    region.span.longitudeDelta = 0.032f;
    region.span.latitudeDelta = 0.032f;
    [mapview setRegion:region animated:YES];

    MapPin *ann = [[MapPin alloc] init];
    ann.title = @"test Town";
    ann.subtitle = @"test Nation";
    ann.coordinate = region.center;
    ann.coordinate = region.center;
    [mapview addAnnotation:ann];

    MKCoordinateRegion region2 = { {0.0, 0.0}, {0.0,0.0}};
    region2.center.latitude = 55.703904;
    region2.center.longitude = 13.201207;
    region2.span.longitudeDelta = 0.032f;
    region2.span.latitudeDelta = 0.032f;
    [mapview setRegion:region2 animated:YES];

    MapPin *ann2 = [[MapPin alloc] init];
    ann2.title = @"test Town";
    ann2.subtitle = @"test Nation";
    ann2.coordinate = region2.center;
    ann2.coordinate = region2.center;
    [mapview addAnnotation:ann2];

    ScrollView.scrollEnabled = YES;
    [ScrollView setContentSize:CGSizeMake(320, 515)];   
}

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{     
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    static NSString* AnnotationIdentifier = @"AnnotationIdentifier";
    MKPinAnnotationView* pinView = [[MKPinAnnotationView alloc]
                                    initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
    pinView.animatesDrop=YES;
    pinView.canShowCallout=YES;
    pinView.pinColor= MKPinAnnotationColorGreen;

    pinView.enabled = YES;
    pinView.canShowCallout = YES;
    pinView.image=[UIImage imageNamed:@"test.png"]; //here I am giving the image


    return pinView;
}
Ben
  • 91
  • 1
  • 6
  • 1
    I think what u need is to add `MKMapViewDelegate` in the `@interface...` declaration of your `FirstViewController`, and to set `mapview.delegate = self` in `viewDidLoad` for example. Without these two lines the other method (`-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation`) is not being called. – Javito_009 Apr 27 '15 at 15:02
  • 1
    Although you should make sure the map view's delegate outlet is connected in storyboard to the view controller, the real problem is that the code in viewForAnnotation is creating an MKPinAnnotationView (tends to ignore custom image) instead of a plain MKAnnotationView (for custom images/views). –  Apr 27 '15 at 16:58
  • So I added MKMapViewDelegate to [@interface] which looks now like this [@interface FirstViewController : UIViewController {] and put the [mapview.delegate = self;] inside the viewdidload. But this still does not solve the issue. – Ben Apr 27 '15 at 17:04

3 Answers3

0

See my other answer for working implementation.

Setting an IBOutlet delegate:

Since you're using an IBOutlet for your MKMapView you should control-drag from your MKMapView in your storyboard/xib file to the ViewController/"File's Owner" and select "delegate" from the popup.

Here a SO answer that covers creating custom pins: Custom pins

Also,

pinView.image=[UIImage imageNamed:@"test.png"]; 

should be

pinView.image=[UIImage imageNamed:@"test"];

Reference: Image from imageNamed:

Community
  • 1
  • 1
NSWill
  • 659
  • 8
  • 15
  • Side note: Generally your IBOutlets should be "weak". Checkout the following reference. http://stackoverflow.com/questions/7678469/should-iboutlets-be-strong-or-weak-under-arc – NSWill Apr 27 '15 at 16:47
0

The following worked for me:

  1. Make sure MapKit.framework has been added to your project.
  2. Make sure test.png is in your project (preferably in Images.xcassets)
  3. Control-drag from your mapView in your storyboard to the ViewController and connect "delegate".

Then...

#import "MapPin.h"
#import <MapKit/MapKit.h>

@interface ViewController () <MKMapViewDelegate>

@property (weak, nonatomic) IBOutlet MKMapView *mapview;

@end

@implementation ViewController

- (void)viewDidLoad
{
    MKCoordinateRegion region = { {0.0, 0.0}, {0.0,0.0}};
    region.center.latitude = 55.709900;
    region.center.longitude = 13.201207;
    region.span.longitudeDelta = 0.032f;
    region.span.latitudeDelta = 0.032f;
    [self.mapview setRegion:region animated:YES];

    MapPin *ann = [[MapPin alloc] init];
    ann.title = @"test Town";
    ann.subtitle = @"test Nation";
    ann.coordinate = region.center;
    ann.coordinate = region.center;
    [self.mapview addAnnotation:ann];

    MKCoordinateRegion region2 = { {0.0, 0.0}, {0.0,0.0}};
    region2.center.latitude = 55.703904;
    region2.center.longitude = 13.201207;
    region2.span.longitudeDelta = 0.032f;
    region2.span.latitudeDelta = 0.032f;
    [self.mapview setRegion:region2 animated:YES];

    MapPin *ann2 = [[MapPin alloc] init];
    ann2.title = @"test Town";
    ann2.subtitle = @"test Nation";
    ann2.coordinate = region2.center;
    ann2.coordinate = region2.center;
    [self.mapview addAnnotation:ann2];
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return nil;
    }

    static NSString* AnnotationIdentifier = @"AnnotationIdentifier";
    MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
    if(annotationView) {
        return annotationView;
    } else {
        MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation
                                                                         reuseIdentifier:AnnotationIdentifier];
        annotationView.image = [UIImage imageNamed:@"test"];
        return annotationView;
    }
}
@end
NSWill
  • 659
  • 8
  • 15
0

So I have followed the guidelines above, added the line of code and step3. Control-drag from your mapView in your storyboard to the ViewController and connect "delegate". which I named "pin".

But my image wont appear...I'll paste the new code again..there must be something wrong in it.

//Viewcontroller.h

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

@interface FirstViewController : UIViewController <UIAlertViewDelegate, UIWebViewDelegate, MKMapViewDelegate> {

    MKMapView *mapview;

}
- (IBAction)information;
@property (strong, nonatomic) IBOutlet UIScrollView *ScrollView;
@property (strong, nonatomic) IBOutlet UIImageView *image;
@property (retain, nonatomic) IBOutlet MKMapView *mapview;
@property (strong, nonatomic) IBOutlet MKMapView *pin;  

- (IBAction)showMenu;
- (IBAction)setMap:(id)sender;
- (IBAction)GetLocation:(id)sender;

@end

//Viewcontroller.m

#import "FirstViewController.h"
#import "MapPin.h"

@implementation FirstViewController

@synthesize ScrollView, image;
@synthesize mapview;
@synthesize pin;

- (void)viewDidLoad{

    MKCoordinateRegion region = { {0.0, 0.0}, {0.0,0.0}};
    region.center.latitude = 55.709900;
    region.center.longitude = 13.201207;
    region.span.longitudeDelta = 0.032f;
    region.span.latitudeDelta = 0.032f;
    [self.mapview setRegion:region animated:YES];

    MapPin *ann = [[MapPin alloc] init];
    ann.title = @"test Town";
    ann.subtitle = @"test Nation";
    ann.coordinate = region.center;
    ann.coordinate = region.center;
    [self.mapview addAnnotation:ann];

    MKCoordinateRegion region2 = { {0.0, 0.0}, {0.0,0.0}};
    region2.center.latitude = 55.703904;
    region2.center.longitude = 13.201207;
    region2.span.longitudeDelta = 0.032f;
    region2.span.latitudeDelta = 0.032f;
    [self.mapview setRegion:region2 animated:YES];

    MapPin *ann2 = [[MapPin alloc] init];
    ann2.title = @"test Town";
    ann2.subtitle = @"test Nation";
    ann2.coordinate = region2.center;
    ann2.coordinate = region2.center;
    [self.mapview addAnnotation:ann2];

    ScrollView.scrollEnabled = YES;
    [ScrollView setContentSize:CGSizeMake(320, 515)];   
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{     
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
    return nil;
}

static NSString* AnnotationIdentifier = @"AnnotationIdentifier";
MKAnnotationView *annotationView = [mapView  dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if(annotationView) {
    return annotationView;
} else {
    MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation
                                                                    reuseIdentifier:AnnotationIdentifier];
    annotationView.image = [UIImage imageNamed:@"test"];
    return annotationView;
}
}

@end
Ben
  • 91
  • 1
  • 6
  • I solved it by adding mapView.delegate = self; into the viewdidload – Ben Apr 28 '15 at 11:08
  • 1
    1) You **don't** create a separate outlet for the delegate. You connect the delegate outlet already on the mapview to the vc (so the map view will have two connections to the view controller: itself and its delegate). The _alternative_ to connecting the delete outlet in storyboard is to do it in code like you did. 2) You may want to start learning iOS with a simpler project. 3) You should have updated your Question with this updated code instead of posting it as an Answer. Take the SO tour to see how things work here. –  Apr 28 '15 at 11:14