News

Here you can find some of the latest news from the mobile design and development world.

MapKit: tap and hold to drop a pin on the map

04 February

Not many people are aware of this but the Maps app on the iPhone and iPad allows you to tap and hold to drop an annotation/pin on the map.

Once the pin is dropped the App uses reverse geocoding (available with MapKit – details here) to get location details for a specific coordinate.

I’ve been working on a project where I’d like to allow users to submit locations by tapping on the map. It turns this is pretty easy to implement:

First we need to setup a gesture recogniser for a long press (tap and hold)

[objc]
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGesture:)];
[self.mapView addGestureRecognizer:longPressGesture];
[longPressGesture release];
[/objc]

Next we create the handleLongPressGesture: method which will handle the tap and hold action

[objc]
-(void)handleLongPressGesture:(UIGestureRecognizer*)sender {
// This is important if you only want to receive one tap and hold event
if (sender.state == UIGestureRecognizerStateEnded)
{
[self.mapView removeGestureRecognizer:sender];
}
else
{
// Here we get the CGPoint for the touch and convert it to latitude and longitude coordinates to display on the map
CGPoint point = [sender locationInView:self.mapView];
CLLocationCoordinate2D locCoord = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
// Then all you have to do is create the annotation and add it to the map
YourAnnotation *dropPin = [[YourAnnotation alloc] init];
dropPin.latitude = [NSNumber numberWithDouble:locCoord.latitude];
dropPin.longitude = [NSNumber numberWithDouble:locCoord.longitude];
[self.mapView addAnnotation:dropPin];
[dropPin release];
}
}
[/objc]

And that should do the trick! Let me know how you go and if you have any questions in the comments section below.

4 Responses to “MapKit: tap and hold to drop a pin on the map”

  1. Pedro Bastos May 31, 2011 at 2:32 am #

    Hi!
    Great info!

    Disclaimer: I’m a newbie in ObjC. 🙂

    I guess i’ve discovered one tiny problem. If you drag your “finger” while you are still on ‘LongPressureGesture’ it will drop thousands and thousands of pins while you move it.

    One way to solve it, is doing the “removeGestureRecognizer:sender” in the beginning of the method(handleLongPressureGesture).

    Nevertheless that behaviour is not intended in my app… I want to give the user the permission to insert as many ‘pins’ as he wants, but if i removeGestureRecognizer… i’m missing the right spot to add it again. I’m sure i’ll make it, nevertheless thx for the great info!

    Good luck on your business
    (hope the english is ok)

  2. Rog May 31, 2011 at 9:39 am #

    Hey Pedro,

    Thanks for your comment! I had the exact same issue as you when I started looking into this so I also added a check for UIGestureRecognizerStateChanged. In this case, if the gesture changes from a “long pressure” to “drag” for instance, I remove the UIGestureRecogniser object.

    In your case, instead of removing the recogniser, you can simply skip the “pin add/drop” part of the code. Here’s a suggestion:

    [objc]if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateChanged)
    return;
    // Otherwise continue with add pin method
    [/objc]

    Let us know how you go!
    Um abraco,
    Rog

  3. Pedro Bastos June 1, 2011 at 7:43 pm #

    Awesome, i’ve just solved it this morning with the exact same solution, came to write about it… and you already had written it. Great job!

    Nevertheless thx for the short answer.

    Um abraço, 🙂

    Pedro

  4. gunjan July 9, 2012 at 11:32 pm #

    what is Your Annotation here??