Custom Pin Image for MapKit Annotation - ios

I want to use my Pin (not default).
I tried above code. First, I can see default pin. When I touched showMyLocation, after I touched sightLocation, default pin change with my custom pin. I want to show my custom pin in first view.
TOCGSightAnnotation.h
#interface TOCGSightAnnotation : NSObject <MKAnnotation>
#property (strong, nonatomic) NSString *title;
#property (nonatomic,assign) CLLocationCoordinate2D coordinate;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title;
#end
TOCGSightAnnotation.m
#implementation TOCGSightAnnotation
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title
{
if ((self = [super init])) {
self.coordinate =coordinate;
self.title = title;
}
return self;
}
#end
TOCGSightseeingMapKitViewController.h
#interface TOCGSightseeingMapKitViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
#property (strong) NSNumber *latitude;
#property (strong) NSNumber *longitude;
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (strong, nonatomic) CLLocationManager * locationManager;
#end
TOCGSightseeingMapKitViewController.m
#import "TOCGSightseeingMapKitViewController.h"
#import "TOCGSightAnnotation.h"
CLLocationCoordinate2D sightCoordinate;
MKCoordinateRegion region;
#interface TOCGSightseeingMapKitViewController ()
#end
#implementation TOCGSightseeingMapKitViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
[self.locationManager startUpdatingLocation];
sightCoordinate = CLLocationCoordinate2DMake([self.latitude doubleValue], [self.longitude doubleValue]);
TOCGSightAnnotation *annotation = [[TOCGSightAnnotation alloc] initWithCoordinate:sightCoordinate title:#"Sight Title"];
[self.mapView addAnnotation:annotation];
region =
MKCoordinateRegionMakeWithDistance(sightCoordinate, 500, 500);
[self.mapView setRegion:region animated:YES];
}
- (IBAction)myLocation:(id)sender
{
self.mapView.delegate = self;
self.mapView.showsUserLocation = YES;
[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
}
- (IBAction)sightLocation:(id)sender
{
[self.mapView setRegion:region animated:YES];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView
viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
if ([annotation isKindOfClass:[TOCGSightAnnotation class]])
{
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView
dequeueReusableAnnotationViewWithIdentifier:#"CustomPinAnnotationView"];
if (!pinView)
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"CustomPinAnnotationView"];
pinView.image = [UIImage imageNamed:#"mapIcon.png"];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
}
else
pinView.annotation = annotation;
return pinView;
}
return nil;
}

The reason is simple. The method
- (MKAnnotationView *)mapView:(MKMapView *)mapView
viewForAnnotation:(id <MKAnnotation>)annotation
will get called only if you set the MKMapViewDelegate. As long as you didn't touch the button that calls the IBAction
- (IBAction)myLocation:(id)sender
the delegate is not set, so the delegate methods are not called. Try moving the line
self.mapView.delegate = self;
after your MKMapView allocation.

I tried this and it works.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
[self.locationManager startUpdatingLocation];
}
- (void)viewDidAppear:(BOOL)animated
{
self.mapView.delegate = self;
sightCoordinate = CLLocationCoordinate2DMake([self.latitude doubleValue], [self.longitude doubleValue]);
TOCGSightAnnotation *annotation = [[TOCGSightAnnotation alloc] initWithCoordinate:sightCoordinate title:#"Sight Title"];
[self.mapView addAnnotation:annotation];
region =
MKCoordinateRegionMakeWithDistance(sightCoordinate, 500, 500);
[self.mapView setRegion:region animated:YES];
}

Related

MapView Application

I have written simple mapView application.It is showing two kind of problems.
1- Execution is stopping on Thread 1: signal SIGABRT error.
2- This function is showing compile time error .
- (IBAction)findMe:(id)sender {
If( [[toggleButton titleForState:UIControlStateNormal] isEqualToString:#"Find Me"] )
{
[toggleButton setTitle:#"Hide Me" forState:UIControlStateNormal];
mapView.showsUserLocation=YES;
}
else
{
[toggleButton setTitle:#"Find Me" forState:UIControlStateNormal];
mapView.showsUserLocation=NO;
}
}
How to remove these error ?
I want put coordinates of more then one location in my code i want to show loc.png icon on map corresponding to those coordinates how i can accomplish this task?
You can see the sample project from this link: https://drive.google.com/open?id=0B5pNDpbvZ8SnRmNFS0pjVnJFWHc
You are getting compile time error for 3 reasons:
1) The "If" you are using in if-else condition should be "if" i.e lowercase.
2). You have an IBOutlet connect to findMe button in storyboard which do not exist in your view controller. So either remove it or add it.
3)You are using MKMapView but you didn't added the MapKit Framework in "Link Binaries" in build phases option of your project.
Please do all these steps to have your code compiled & executed error free.
Answer to your query:
I want put coordinates of more then one location in my code i want to show loc.png icon on map corresponding to those coordinates how i can accomplish this task?
Here is the code for ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate, MKMapViewDelegate>
#end
Here is the code for ViewController.m
#import "ViewController.h"
#import "MyAnnotation.h"
#import <MapKit/MapKit.h>
#interface ViewController ()
#property (strong, nonatomic) IBOutlet MKMapView *myMapView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// setup the map view, delegate and current location
[self.myMapView setDelegate:self];
self.myMapView.mapType = MKMapTypeStandard;
CLLocationCoordinate2D myLocation = CLLocationCoordinate2DMake(25.085130,-77.331428);
[self.myMapView setCenterCoordinate:myLocation];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(myLocation, 2000, 2000);
region.center = self.myMapView.centerCoordinate;
self.myMapView.showsUserLocation = YES;
[self.myMapView setRegion:region animated:YES];
[self dropPins];
}
-(void)dropPins {
NSMutableArray *annotationArray = [[NSMutableArray alloc] init];
CLLocationCoordinate2D location1 = CLLocationCoordinate2DMake(25.085130, -77.331428);
MyAnnotation *annotation1 = [[MyAnnotation alloc] initWithCoordinates:location1 image:#"loc.png"];
[annotationArray addObject:annotation1];
[self.myMapView addAnnotations:annotationArray];
[annotationArray removeAllObjects];
CLLocationCoordinate2D location2 = CLLocationCoordinate2DMake(25.085130, -77.336428);
MyAnnotation *annotation2 = [[MyAnnotation alloc] initWithCoordinates:location2 image:#"loc.png"];
[annotationArray addObject:annotation2];
[self.myMapView addAnnotations:annotationArray];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[MyAnnotation class]])
{
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[self.myMapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
} else
{
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.canShowCallout = NO;
if([[(MyAnnotation *)annotationView.annotation image] isEqualToString:#"pin1.png"])
annotationView.image = [UIImage imageNamed:#"loc.png"];
if([[(MyAnnotation *)annotationView.annotation image] isEqualToString:#"pin2.png"])
annotationView.image = [UIImage imageNamed:#"loc.png"];
return annotationView;
}
return nil;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Add new files MyAnnotation.h/MyAnnotation.m
Here is the code for MyAnnotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MyAnnotation : NSObject <MKAnnotation>
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy, readonly) NSString *image;
-(id)initWithCoordinates:(CLLocationCoordinate2D) paramCoordinates
image:(NSString *) paramImage;
#end
Here is the code for MyAnnotation.m
#import "MyAnnotation.h"
#implementation MyAnnotation
-(id)initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates
image:(NSString *)paramImage
{
self = [super init];
if(self != nil)
{
_coordinate = paramCoordinates;
_image = paramImage;
}
return (self);
}
#end

Adding title to annotations

I have this code that displays 4 points on a map with a custom image. I have begun to learn that perhaps the way I structured it is not optimal but it is what I have.
Please help me to learn how to make the titles I created show up on the map with the custom poi when someone taps it.
I have two classes that work with the view. The classes are MapAnnotation and LocationsViewController.
Here is the code for each.
MapAnnotation.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapAnnotation : NSObject <MKAnnotation, MKMapViewDelegate>
{
CLLocationCoordinate2D _coordinate;
NSString * title;
}
#property (nonatomic, copy) NSString *title;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate;
#end
MapAnnotation.m
#import "MapAnnotation.h"
#import "LocationsViewController.h"
#implementation MapAnnotation
#synthesize coordinate = _coordinate;
#synthesize title;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate
{
self = [super init];
if (self != nil)
{
_coordinate = coordinate;
}
return self;
}
#end
LocationsViewController.h
#import "TechBookAppDelegate.h"
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface LocationsViewController : UIViewController <MKMapViewDelegate, MKAnnotation>
{
IBOutlet MKMapView *worldView;
IBOutlet UIActivityIndicatorView *activityIndicator;
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id < MKAnnotation >)annotation;
#end
LocationsViewController.m
#import "LocationsViewController.h"
#import "MapAnnotation.h"
#interface LocationsViewController ()
#end
#implementation LocationsViewController
#synthesize coordinate = _coordinate;
#synthesize title;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Initialization code
}
return self;
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil)
{
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
}
annotationView.image = [UIImage imageNamed:#"app_icon_sm.png"];
annotationView.annotation = annotation;
return annotationView;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
worldView.showsUserLocation = NO;
CLLocationCoordinate2D wisconsin = {.latitude = 45.620775, .longitude = -89.47844};
CLLocationCoordinate2D pennsyvainia = {.latitude = 39.912417, .longitude = -77.663268};
CLLocationCoordinate2D nevada = {.latitude = 36.054362, .longitude = -115.020470};
CLLocationCoordinate2D texas = {.latitude = 32.555038, .longitude = -94.295592};
MapAnnotation *pinWI = [[MapAnnotation alloc] initWithCoordinate: wisconsin] ;
MapAnnotation *pinPA = [[MapAnnotation alloc] initWithCoordinate: pennsyvainia];
MapAnnotation *pinNV = [[MapAnnotation alloc] initWithCoordinate: nevada];
MapAnnotation *pinTX = [[MapAnnotation alloc] initWithCoordinate: texas];
//UIImage *star = [UIImage imageNamed:#"locations_marker.png"];
//////////////////
pinWI.title = #"Rhinelander, WI";///////
pinPA.title = #"Chambersburg, PA";//////I dont understand why these do not output a
pinNV.title = #"Henderson, NV";/////////title if the title property is a part of the
pinTX.title = #"Marshall, TX";////////// MKAnnotation
//////////////////
[worldView addAnnotation:pinTX];
[worldView addAnnotation:pinNV];
[worldView addAnnotation:pinWI];
[worldView addAnnotation:pinPA];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I suppose I need a function to create the titles? I really am hoping I do not have to create more classes to do this.
Your main question is:
How to make the titles I created show up on the map with the custom poi when someone taps it.
In the viewForAnnotation delegate method, you need to set the canShowCallout property of the annotation view to YES (the default is NO):
if (annotationView == nil)
{
annotationView = [[MKAnnotationView alloc] initWithAnnotation...
annotationView.canShowCallout = YES; // <-- add this line
}
Some additional comments unrelated to the question:
In MapAnnotation.h, this class will only be implementing MKAnnotation, not MKMapViewDelegate so remove it from the protocol list to avoid potential compiler warnings and to make the code clearer and cleaner:
#interface MapAnnotation : NSObject <MKAnnotation>
In MapAnnotation.m, you don't need the #import "LocationsViewController.h". Remove it.
In LocationsViewController.h, this class will not be implementing MKAnnotation so remove it from the protocol list to avoid potential compiler warnings and to make the code clearer and cleaner:
#interface LocationsViewController : UIViewController <MKMapViewDelegate>
Also in LocationsViewController.h, it's unnecessary to declare the delegate methods you'll be implementing. You can remove the viewForAnnotation declaration.
In LocationsViewController.m, the #synthesizes for coordinate and title don't belong here. Remove them.
-(void)locatePlaceonMap:(NSDictionary*)dic
{
[map_bar setScrollEnabled:YES];
map_bar.delegate = self;
MKCoordinateRegion zoomIn = map_bar.region;
zoomIn.span.latitudeDelta = 0.1f;
zoomIn.span.longitudeDelta = 0.1f;
zoomIn.center.latitude = ApplicationDelegate.latitude;
zoomIn.center.longitude = ApplicationDelegate.longitude;
[map_bar setRegion:zoomIn animated:NO];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
annotation.title = [dic valueForKey:#"vName"];
annotation.subtitle = [dic valueForKey:#"t_long_address"];
CLLocationCoordinate2D newlocation = [map_bar.userLocation coordinate];
newlocation.latitude=[[dic valueForKey:#"dLat"]doubleValue];
newlocation.longitude=[[dic valueForKey:#"dLong"]doubleValue];
annotation.coordinate = newlocation;
[map_bar addAnnotation:annotation];
}
#pragma mark MkMapViewDelegate Methods
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation: (id<MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = nil;
static NSString *defaultPinID = #"ReusedPin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
if (annotation == mapView.userLocation) {
return nil;
}else{
pinView.image = [UIImage imageNamed:#"pin_trophy.png"];
pinView.pinColor = MKPinAnnotationColorRed;
}
pinView.canShowCallout = YES;
pinView.animatesDrop = NO;
return pinView;
}

Change map pin (color or image)

I know this is a question asked a lot. I have been reading through many of the questions on here regarding this for a while. I was hoping someone would have a simpler way using the code I have to replace the pins on my map with an image. I am still very new to objective c.The code I have is very short and easy. Most of what I have found online to post pins to a map is very long and drawn out. I have the following classes and controllers for my map view:
LocationsViewController.h
#import "TechBookAppDelegate.h"
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface LocationsViewController : UIViewController <MKMapViewDelegate>
{
IBOutlet MKMapView *worldView;
IBOutlet UIActivityIndicatorView *activityIndicator;
}
#end
LocationsViewController.m
#import "LocationsViewController.h"
#import "MapAnnotation.h"
#interface LocationsViewController ()
#end
#implementation LocationsViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Initialization code
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
CLLocationCoordinate2D wisconsin = {.latitude = xx.xxxxxxx, .longitude = -xx.xxxxxx};
CLLocationCoordinate2D pennsyvainia = {.latitude = xx.xxxxxxx, .longitude = -xx.xxxxxx};
CLLocationCoordinate2D nevada = {.latitude = xx.xxxxxxx, .longitude = -xx.xxxxxx};
CLLocationCoordinate2D texas = {.latitude = xx.xxxxxxx, .longitude = -xx.xxxxxx};
MapAnnotation *pinWI = [[MapAnnotation alloc] initWithCoordinate: wisconsin];
MapAnnotation *pinPA = [[MapAnnotation alloc] initWithCoordinate: pennsyvainia];
MapAnnotation *pinNV = [[MapAnnotation alloc] initWithCoordinate: nevada];
MapAnnotation *pinTX = [[MapAnnotation alloc] initWithCoordinate: texas];
[worldView addAnnotation:pinTX];
[worldView addAnnotation:pinNV];
[worldView addAnnotation:pinWI];
[worldView addAnnotation:pinPA];
}
MapAnnotation.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapAnnotation : NSObject <MKAnnotation> {
CLLocationCoordinate2D _coordinate;
MKAnnotationView *mapView;
}
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate;
#end
MapAnnotation.m
#import "MapAnnotation.h"
#import "LocationsViewController.h"
#implementation MapAnnotation
#synthesize coordinate = _coordinate;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate
{
self = [super init];
if (self != nil)
{
_coordinate = coordinate;
}
return self;
}
#end
I have tried to implement methods similar to this:
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{.......
with various types of code but to no avail. Not sure what I am doing wrong. Isn't there a shorter way to do what I am thinking than this than what I have seen so far online.
I was hoping there was something similar to :
MapAnnotation *pinWI = [[[MapAnnotation alloc] initWithCoordinate: wisconsin] initWithPinImage:#"imagename.png"];
or could I implement something similar to this:
pinWI:MKPinAnnotationColorGreen;
only with a image location defined?
or something along those lines. Thanks in advance for everyones help and patience with a newbie.
I really need to change the pin to a custom image. One coding schema I tried was this:
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil)
{
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];
}
annotationView.image = [UIImage imageNamed:#"location.png"];
annotationView.annotation = annotation;
return annotationView;
}
WORKING CODE:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[worldView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil)
{
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
}
annotationView.image = [UIImage imageNamed:#"locations_marker.png"];
annotationView.annotation = annotation;
return annotationView;
}
add the type property(example-firstPin, secondPin,thirdPin etc) to your custom MapViewAnnotation class.
MapViewAnnotation *newAnnotation = [[MapViewAnnotation alloc] init...
newAnnotation.type = #"firstPin"; // <-- set property in annotation
[self.mapView addAnnotation:newAnnotation];
and in your - (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation method put a simple check
MapViewAnnotation *mvAnn = (MapViewAnnotation *)annotation;
if ([mvAnn.type isEqualToString:#"firstPin"])
{
annView.pinColor = MKPinAnnotationColorGreen;
}
else if ([mvAnn.type isEqualToString:#"secondPin"])
{
annView.pinColor = MKPinAnnotationColorRed;
}
else if ([mvAnn.type isEqualToString:#"thirdPin"])
{
annView.pinColor = MKPinAnnotationColorOrange;
}

ios: mapKit viewForAnnotation disappears popup Title from PIN?

I am trying to create draggable custom pin with Title popup with MapKit. but when I implement viewForAnnotation to make PIN appear as custom image, its disappears pop title as if I youch Pin on map it does not show titla popup,
while if I comments viewForAnnotation it works fine, but I want both things custom image and popup title when tap pin.
below is code
- (void)viewDidLoad
{
MKCoordinateRegion newRegion = MKCoordinateRegionMakeWithDistance(LocCoordinate, 20000, 20000);
DDAnnotation *point = [[DDAnnotation alloc] init];
[point setCoordinate:mapCenter];
[point setTitle:#"Where am I"];
[point setSubtitle:#"I am here"];
[self.mvTripMap addAnnotation:point];
[self.mvTripMap setRegion:newRegion animated:YES];
[super viewDidLoad];
}
-(MKAnnotationView *)mapView:(MKMapView *)MapView viewForAnnotation:(id<MKAnnotation>)annotation{
static NSString *cabAnnotationIdentifier=#"cabAnnotationIdentifier";
MKAnnotationView *annotationView=[MapView dequeueReusableAnnotationViewWithIdentifier:cabAnnotationIdentifier];
if(!annotationView){
annotationView=[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:cabAnnotationIdentifier];
annotationView.image=[UIImage imageNamed:#"start.png"];
annotationView.draggable = YES;
}
return annotationView;
}
DDAnnotation.h
#import <MapKit/MapKit.h>
#interface DDAnnotation : MKPlacemark {
CLLocationCoordinate2D coordinate_;
NSString *title_;
NSString *subtitle_;
}
// Re-declare MKAnnotation's readonly property 'coordinate' to readwrite.
#property (nonatomic, readwrite, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, retain) NSString *title;
#property (nonatomic, retain) NSString *subtitle;
#end
DDAnnotation.m
#import "DDAnnotation.h"
#implementation DDAnnotation
#synthesize coordinate = coordinate_;
#synthesize title = title_;
#synthesize subtitle = subtitle_;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate addressDictionary:(NSDictionary *)addressDictionary {
if ((self = [super initWithCoordinate:coordinate addressDictionary:addressDictionary])) {
self.coordinate = coordinate;
}
return self;
}
#end
Just put annotationView.canShowCallout= YES; and it will work
updated code
-(MKAnnotationView *)mapView:(MKMapView *)MapView viewForAnnotation:(id<MKAnnotation>)annotation{
static NSString *cabAnnotationIdentifier=#"cabAnnotationIdentifier";
MKAnnotationView *annotationView=[MapView dequeueReusableAnnotationViewWithIdentifier:cabAnnotationIdentifier];
if(!annotationView){
annotationView=[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:cabAnnotationIdentifier];
annotationView.image=[UIImage imageNamed:#"start.png"];
annotationView.draggable = YES;
annotationView.canShowCallout= YES;
}
return annotationView;
}

MKMapView Delegate Methods not working

I just wanted to add a Polyline to my Map which is displayed in a tableviewcell. Unfortunately
the delegate methods are not called... Would be nice if someone knows why.
My tableview.h:
#import <UIKit/UIKit.h>
#import "Route.h"
#import <MapKit/MapKit.h>
#import <QuartzCore/QuartzCore.h>
#interface RoutesDetailView : UITableViewController<MKMapViewDelegate>{
Route *myRoute;
MKMapView *mapView;
// the view we create for the line on the map
MKPolylineView* _routeLineView;
// the rect that bounds the loaded points
MKMapRect _routeRect;
MKPolyline* _routeLine;
}
#property (nonatomic, retain) Route *myRoute;
#property (nonatomic,retain) MKMapView *mapView;
#property (nonatomic, retain) MKPolyline* routeLine;
#property (nonatomic, retain) MKPolylineView* routeLineView;
-(MKPolyline *) loadRoute: (Route *) theRoute;
#end
And my tableview.m:
#implementation RoutesDetailView
#synthesize myRoute,mapView;
#synthesize routeLine = _routeLine;
#synthesize routeLineView = _routeLineView;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (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.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
MKMapView *myMap = [[MKMapView alloc] initWithFrame:CGRectMake(10, 1, 300 , 300)];
myMap.layer.cornerRadius = 10.0;
[self setMapView:myMap];
[mapView setDelegate:self];
CLLocationCoordinate2D annotationCoord;
annotationCoord.latitude = [[NSString stringWithFormat:#"%#",NSLocalizedString(#"DefaultPointLAT", nil)] doubleValue];
annotationCoord.longitude = [[NSString stringWithFormat:#"%#",NSLocalizedString(#"DefaultPointLONG", nil)] doubleValue];
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = annotationCoord;
MKCoordinateRegion region =
MKCoordinateRegionMakeWithDistance (annotationPoint.coordinate,[[NSString stringWithFormat:#"%#",NSLocalizedString(#"DefaultCircle", nil)] doubleValue], [[NSString stringWithFormat:#"%#",NSLocalizedString(#"DefaultCircle", nil)] doubleValue]);
[mapView setRegion:region animated:NO];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
.
.
.
static NSString *CellIdentifier = #"CellMap";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
[mapView setFrame:CGRectMake(10, 1, cell.frame.size.width-20 , cell.frame.size.height-1)];
[cell addSubview:mapView];
[mapView addOverlay:[self loadRoute:myRoute]];
return cell;
.
.
.
}
#pragma mark - Table view delegate
-(MKPolyline *) loadRoute: (Route *) theRoute
{
MKMapPoint northEastPoint;
MKMapPoint southWestPoint;
// create a c array of points.
MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * theRoute.latitude.count);
for(int idx = 0; idx < theRoute.latitude.count; idx++)
{
CLLocationDegrees latitude = [[[theRoute latitude] objectAtIndex:idx] doubleValue];
CLLocationDegrees longitude = [[[theRoute longitude] objectAtIndex:idx] doubleValue];
// create our coordinate and add it to the correct spot in the array
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
MKMapPoint point = MKMapPointForCoordinate(coordinate);
//
// adjust the bounding box
//
// if it is the first point, just use them, since we have nothing to compare to yet.
if (idx == 0) {
northEastPoint = point;
southWestPoint = point;
}
else
{
if (point.x > northEastPoint.x)
northEastPoint.x = point.x;
if(point.y > northEastPoint.y)
northEastPoint.y = point.y;
if (point.x < southWestPoint.x)
southWestPoint.x = point.x;
if (point.y < southWestPoint.y)
southWestPoint.y = point.y;
}
pointArr[idx] = point;
}
// create the polyline based on the array of points.
self.routeLine = [MKPolyline polylineWithPoints:pointArr count:theRoute.latitude.count];
_routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x - southWestPoint.x, northEastPoint.y - southWestPoint.y);
// clear the memory allocated earlier for the points
free(pointArr);
return self.routeLine;
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay
{
NSLog(#"DELEGATE CALL");
MKOverlayView* overlayView = nil;
if(overlay == self.routeLine)
{
//if we have not yet created an overlay view for this overlay, create it now.
if(nil == self.routeLineView)
{
self.routeLineView = [[MKPolylineView alloc] initWithPolyline:self.routeLine];
self.routeLineView.fillColor = [UIColor redColor];
self.routeLineView.strokeColor = [UIColor redColor];
self.routeLineView.lineWidth = 15;
}
overlayView = self.routeLineView;
}
return overlayView;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
Try this, I was having the same issue. After trying many combinations this is the one which works.
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapViewController : UIViewController<MKMapViewDelegate> {
MKMapView *mapView;
}
and the implementation...
- (void)viewDidLoad {
[super viewDidLoad];
mapView = [[MKMapView alloc] initWithFrame: CGRectMakeFullScreenIphone];
mapView.delegate = self;
[mapView setMapType: MKMapTypeStandard];
[self.view addSubview: mapView];
MKCoordinateRegion newRegion;
// configure region...
[mapView setRegion:newRegion animated:YES];
CLLocationCoordinate2D coordinate;
//configure coordinate...
MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
[annotation setCoordinate:coordinate];
[annotation setTitle:#"TEST"];
[mapView addAnnotation:annotation];
}
The simple code above works fine and delegate's methods were called.
if you are running the application in simulator, then the
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay
this delegate method will not get called, you need to run it on iOS Device.
The first Meth is
mapView:regionDidChangeAnimated:
and the second is
mapView:didUpdateUserLocation:
Header File
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ViewController : UIViewController <MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (weak, nonatomic) IBOutlet UIButton *searchButton;
#end
Implementation File
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.delegate = self;
self.mapView.mapType = MKMapTypeStandard;
self.mapView.showsUserLocation = YES;
self.searchButton.hidden = YES;
}
- (IBAction)setMapType:(UISegmentedControl *)sender {
switch (sender.selectedSegmentIndex) {
case 0:
self.mapView.mapType = MKMapTypeStandard;
break;
case 1:
self.mapView.mapType = MKMapTypeSatellite;
break;
case 2:
self.mapView.mapType = MKMapTypeHybrid;
break;
default:
break;
}
}
- (IBAction)zoomToCurrentLocation:(UIBarButtonItem *)sender {
float spanX = 0.00725;
float spanY = 0.00725;
MKCoordinateRegion region;
region.center.latitude = self.mapView.userLocation.coordinate.latitude;
region.center.longitude = self.mapView.userLocation.coordinate.longitude;
region.span.latitudeDelta = spanX;
region.span.longitudeDelta = spanY;
self.searchButton.hidden = YES;
[self.mapView setRegion:region animated:YES];
}
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
self.searchButton.hidden = NO;
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
[self.mapView setCenterCoordinate:userLocation.coordinate animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

Resources