The annotation pin is draggable but I couldn't drop it to the destination location. The problem is how could I get the destination location's coordinate where i drop the annotation pin? Any method exist?
Edit 1:
The center of the annotation pin seems never changed where ever I drop the pin.
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState
fromOldState:(MKAnnotationViewDragState)oldState
{
if (newState == MKAnnotationViewDragStateEnding)
{
NSLog(@"x is %f", annotationView.center.x);
NSLog(@"y is %f", annotationView.center.y);
CGPoint dropPoint = CGPointMake(annotationView.center.x, annotationView.center.y);
CLLocationCoordinate2D newCoordinate = [self.mapView convertPoint:dropPoint toCoordinateFromView:annotationView.superview];
[annotationView.annotation setCoordinate:newCoordinate];
}
}
Edit 2:
Annotation.h
@property (nonatomic,readwrite,assign) CLLocationCoordinate2D coordinate;
Annotation.m
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
coordinate = newCoordinate;
}
Edit 3: where ever I drag the pin, the NSLog out put of the droppedAt is always the same.
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState
fromOldState:(MKAnnotationViewDragState)oldState
{
if (newState == MKAnnotationViewDragStateEnding)
{
CLLocationCoordinate2D droppedAt = annotationView.annotation.coordinate;
NSLog(@"Pin dropped at %f,%f", droppedAt.latitude, droppedAt.longitude);
}
}
Edit 4:
Annotaion.m @dynamic startAddr;
- (CLLocationCoordinate2D)coordinate
{
coordinate.latitude = [self.startAddr.latitude doubleValue];
coordinate.longitude = [self.startAddr.longitude doubleValue];
return coordinate;
}
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
//I need to update the self.startAddr.latitude and longitude here. Problem solved.
self.startAddr.latitude = [NSNumber numberWithDouble:newCoordinate.latitude];
self.startAddr.longitude = [NSNumber numberWithDouble:newCoordinate.longitude];
coordinate = newCoordinate;
}
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?
First you have to create a custom annotation like this:
MyAnnotation.h
#import <MapKit/MapKit.h>
@interface MyAnnotation : NSObject <MKAnnotation>{
CLLocationCoordinate2D coordinate;
}
- (id)initWithCoordinate:(CLLocationCoordinate2D)coord;
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate;
@end
MyAnnotation.m
#import "MyAnnotation.h"
@implementation MyAnnotation
@synthesize coordinate;
- (NSString *)subtitle{
return nil;
}
- (NSString *)title{
return nil;
}
-(id)initWithCoordinate:(CLLocationCoordinate2D)coord {
coordinate=coord;
return self;
}
-(CLLocationCoordinate2D)coord
{
return coordinate;
}
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
coordinate = newCoordinate;
}
@end
After that, you just have to use your annotation like this:
// Assuming you have imported MyAnnotation.h and you have a self.map property pointing to a MKMapView
MyAnnotation *myPin = [[MyAnnotation alloc] initWithCoordinate:self.map.centerCoordinate]; // Or whatever coordinates...
[self.map addAnnotation:myPin];
Also, you have to return a view for your annotation. You can do so like this:
- (MKAnnotationView *) mapView: (MKMapView *) mapView viewForAnnotation: (id<MKAnnotation>) annotation {
MKPinAnnotationView *pin = (MKPinAnnotationView *) [self.map dequeueReusableAnnotationViewWithIdentifier: @"myPin"];
if (pin == nil) {
pin = [[[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier: @"myPin"] autorelease]; // If you use ARC, take out 'autorelease'
} else {
pin.annotation = annotation;
}
pin.animatesDrop = YES;
pin.draggable = YES;
return pin;
}
Then, once you have adopted the MKMapViewDelegate
protocol in your controller, you grab the coordinates of a pin after dragging it like this:
- (void)mapView:(MKMapView *)mapView
annotationView:(MKAnnotationView *)annotationView
didChangeDragState:(MKAnnotationViewDragState)newState
fromOldState:(MKAnnotationViewDragState)oldState
{
if (newState == MKAnnotationViewDragStateEnding)
{
CLLocationCoordinate2D droppedAt = annotationView.annotation.coordinate;
NSLog(@"Pin dropped at %f,%f", droppedAt.latitude, droppedAt.longitude);
}
}
Out of the blue, implement the setCoordinates method of your annotation and make a callBAck when your annotation coordinates have changed
edit : beware of the dragState property of your annotation while its moving.
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