How do I drop a pin with MapKit?

2019-01-31 09:43发布

问题:

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?

回答1:

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.



回答2:

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);
}


回答3:

you can get touched location by ,jcesarmobile answer on get tapped coordinates with iphone mapkit and you can drop pin any where as bellow

// Define pin location
CLLocationCoordinate2D pinlocation;
pinlocation.latitude = 51.3883454 ;//set latitude of selected coordinate ;
pinlocation.longitude = 1.4368011 ;//set longitude of selected coordinate;

// Create Annotation point 
MKPointAnnotation *Pin = [[MKPointAnnotation alloc]init];
Pin.coordinate = pinlocation;
Pin.title = @"Annotation Title";
Pin.subtitle = @"Annotation Subtitle";

// add annotation to mapview
[mapView addAnnotation:Pin];


回答4:

You might also need to set MapView Delegate.

[mkMapView setDelegate:self];

Then call its delegate, viewForAnnotation:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
    MKPinAnnotationView *pinAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                                                    reuseIdentifier:@"current"];
    pinAnnotationView.animatesDrop = YES;
    pinAnnotationView.pinColor = MKPinAnnotationColorRed;
    return pinAnnotationView;
}