I would like to allow the user of my app to pick a location in the map. The native map has a "drop pin" feature where you can locate something by dropping a pin. How can I do this in MapKit?
Tap the Share icon at the bottom of the screen to send the pin to one of your contacts. In the list of your most-used contacts, click the profile icon of the people you want to share the pin with to send them the pin from the app.
To make an annotation draggable, set the annotation view's draggable property to YES. This is normally done in the viewForAnnotation delegate method. If you need to handle when the user stops dragging and drops the annotation, see: how to manage drag and drop for MKAnnotationView on IOS?
You need to create an object that implements the MKAnnotation protocol and then add that object to the MKMapView:
@interface AnnotationDelegate : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString * title;
NSString * subtitle;
}
Instantiate your delegate object and add it to the map:
AnnotationDelegate * annotationDelegate = [[[AnnotationDelegate alloc] initWithCoordinate:coordinate andTitle:title andSubtitle:subt] autorelease];
[self._mapView addAnnotation:annotationDelegate];
The map will access the coordinate property on your AnnotationDelegate to find out where to put the pin on the map.
If you want to customize your annotation view you will need to implement the MKMapViewDelegate viewForAnnotation method on your Map View Controller:
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
If you would like to implement the pin drag functionality you can read about handling annotation touch events in the Apple OS Reference Library.
You can also check out this article on drag drop with mapkit which refers to a working sample library on GitHub. You can get the coordinates of the dragged annotation by checking the _coordinates member on the DDAnnotation object.
There are multiple ways to drop a pin, and you don't specify which way to do it in your question. The first way is to do it programmatically, for that you can use what RedBlueThing wrote, except that you don't really need a custom class (depending on what version of iOS you are targetting). For iOS 4.0 and later you can use this snippet to programmatically drop a pin:
// Create your coordinate
CLLocationCoordinate2D myCoordinate = {2, 2};
//Create your annotation
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
// Set your annotation to point at your coordinate
point.coordinate = myCoordinate;
//If you want to clear other pins/annotations this is how to do it
for (id annotation in self.mapView.annotations) {
[self.mapView removeAnnotation:annotation];
}
//Drop pin on map
[self.mapView addAnnotation:point];
If you want to be able to drop a pin by for example long pressing on the actual mapView, it can be done like this:
// Create a gesture recognizer for long presses (for example in viewDidLoad)
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 0.5; //user needs to press for half a second.
[self.mapView addGestureRecognizer:lpgr]
- (void)handleLongPress:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer.state != UIGestureRecognizerStateBegan) {
return;
}
CGPoint touchPoint = [gestureRecognizer locationInView:self.mapView];
CLLocationCoordinate2D touchMapCoordinate = [self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = touchMapCoordinate;
for (id annotation in self.mapView.annotations) {
[self.mapView removeAnnotation:annotation];
}
[self.mapView addAnnotation:point];
}
If you want to enumerate all the annotations, just use the code in both snippets. This is how you log positions for all annotations:
for (id annotation in self.mapView.annotations) {
NSLog(@"lon: %f, lat %f", ((MKPointAnnotation*)annotation).coordinate.longitude,((MKPointAnnotation*)annotation).coordinate.latitude);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With