Rence
Rence

Reputation: 55

How to drag annotation pin in a mapview?

I have an initial dropped pin in Map View.

What I want to accomplish is to drag that pin anywhere within the map and get the new coordinates from that pin. How to do that? What should I add?

I have this method where I do the initial drop pin.

- (void) performSearch
{
    MKLocalSearchRequest *request =
    [[MKLocalSearchRequest alloc] init];
    request.naturalLanguageQuery = _searchString;
    request.region = _mapView.region;

    _matchingItems = [[NSMutableArray alloc] init];

    MKLocalSearch *search =
    [[MKLocalSearch alloc]initWithRequest:request];

    [search startWithCompletionHandler:^(MKLocalSearchResponse
                                         *response, NSError *error) {
        if (response.mapItems.count == 0)
        NSLog(@"No Matches");
        else
        for (MKMapItem *item in response.mapItems)
        {
            [_matchingItems addObject:item];
            annotation = [[MKPointAnnotation alloc]init];
            annotation.coordinate = item.placemark.coordinate;
            annotation.title = item.name;
            [_mapView addAnnotation:annotation];


            MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance (annotation.coordinate, 800, 800);
            [_mapView setRegion:region animated:NO];
        }
    }];

}

Upvotes: 1

Views: 2321

Answers (1)

AMI289
AMI289

Reputation: 1108

First, conform to the MKMapViewDelegate

//ViewController.m  
@interface ViewController () <MKMapViewDelegate>  
@end  

Then, set the delegate of your map view to be self

-(void)viewDidLoad {  
    [super viewDidLoad];  
    _mapView.delegate = self;  
    ...  
    ...  
  }  

Then implement the following two delegate methods.

The first delegate method returns the view associated with the annotation object, and setting this view to be draggable,
The second method, handles dragging state of an annotation view.

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {  
    MKPinAnnotationView *pin = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:@"pin"];  

  if(!pin) {  
      pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reueseIdentifier:@"pin"];  
    } else {  
      pin.annotation = annotation;  
    }  

  pin.draggable = YES;  

  return pin;  
}  

Here we requesting for an MKPinAnnotationView with the identifier of @"pin",
If we doesn't receive one back, we just create it.
Then we set the view to be draggable.

The above could be enough for moving, and therefore changing, the annotation's coordinates.
If you would like to call some method when a new coordinate is set, you can do this with the second delegate method-

-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState {  
  {  
      if(newState == MKAnnotationViewDragStateStarting)  {  
        NSLog(@"%f, %f", view.annotation.coordinate.latitude, view.annotation.coordinate.longitude);  
        }  

      if(newState == MKAnnotationViewDragStateEnding) {  
        NSLog(@"%f, %f", view.annotation.coordinate.latitude, view.annotation.coordinate.longitude);  
        // Here you can call whatever you want to happen when to annotation coordinates changes  
        }  
  }  

Here you determine when the dragging has actually ended, and then you can call whatever method you like, that will handle the new coordinates.

Note that I've also included an NSLog call when the dragging is starting and ending.
This is just for debugging purposes, so you'll see that the coordinates are actually being changed.

Good luck mate.

Upvotes: 2

Related Questions