2012-05-24 22 views
13

El pin de anotación se puede arrastrar pero no pude soltarlo en la ubicación de destino. El problema es cómo podría obtener la coordenada de la ubicación de destino donde soltaré el pin de anotación. ¿Algún método existe?Arrastre un pin de anotación en una vista de mapa

Edición 1:

El centro del pasador de anotación no parece haber cambiado donde cada vez se me cae el pasador.

- (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]; 

} 
} 

Edición 2:

Annotation.h

@property (nonatomic,readwrite,assign) CLLocationCoordinate2D coordinate; 

Annotation.m

- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate { 
coordinate = newCoordinate; 
} 

Datos 3: donde quiera que arrastra el pasador, el NSLog ou t put of the droppedAt es siempre el mismo.

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

Editar 4:

Annotaion.m @dynamic DirInicial;

- (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; 
} 
+0

@rckoenes thx para su notificación. –

Respuesta

38

En primer lugar hay que crear una anotación personalizada así:

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 

Después de eso, sólo hay que usa tu anotación así:

// 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]; 

Además, debe devolver una vista para la anotación.Puede hacerlo de esta manera:

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

Entonces, una vez que haya adoptado el protocolo de MKMapViewDelegate en su controlador, que agarrar las coordenadas de un alfiler después de arrastrar así:

- (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); 
    } 
} 
+0

¿dónde estableciste la nueva coordenada? –

+1

Es por eso que implementa el método 'setCoordinate'. De la documentación de Apple -> _Anotaciones que admiten arrastrar deberían implementar este método para actualizar la posición de la anotación._ – Alladinian

+0

Actualizo las coordenadas como en mi publicación (simplemente edítelo). Pero parece que no funciona. –

1

De la nada, poner en práctica el método setCoordinates de su anotación y hacer una devolución de llamada cuando sus coordenadas de anotación han cambiado

edición: cuidado de la propiedad dragState de su anotación, mientras que su movimiento.

+0

Thx por tu respuesta. Por favor revisa la actualización de mi publicación. –

1
no hacer

quieres probar a hacer esto:

Ajuste del delegado anotación, a continuación,

- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate { 
    coordinate = newCoordinate; 
    if (self.delegate respondsToSelector:@selector(mapAnnotationCoordinateHaveChanged)) 
    [self.delegate performSelector(@selector(mapAnnotationCoordinateHaveChanged))]; 
} 

En su delegado:

- (void) mapAnnotationCoordinateHaveChanged{ 
//some coordinates update code 
} 
1
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation 
{ 
    MKAnnotationView *a = [ [ MKAnnotationView alloc ] initWithAnnotation:annotation reuseIdentifier:@"currentloc"]; 
    // a.title = @"test"; 
    if (a == nil) 
     a = [ [ MKAnnotationView alloc ] initWithAnnotation:annotation reuseIdentifier: @"currentloc" ]; 

    NSLog(@"%f",a.annotation.coordinate.latitude); 
    NSLog(@"%f",a.annotation.coordinate.longitude); 

    CLLocation* currentLocationMap = [[[CLLocation alloc] initWithLatitude:a.annotation.coordinate.latitude longitude:a.annotation.coordinate.longitude] autorelease]; 
    [self coordinatesToDMS:currentLocationMap]; 


    MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:a reuseIdentifier:@"currentloc"]; 
    if(a.annotation.coordinate.longitude == mapView.userLocation.coordinate.longitude || a.annotation.coordinate.latitude == mapView.userLocation.coordinate.latitude ) 
    { 
     if ([annotation isKindOfClass:MKUserLocation.class]) 
     { 
      //user location view is being requested, 
      //return nil so it uses the default which is a blue dot... 
      return nil; 
     }  
     //a.image = [UIImage imageNamed:@"userlocation.png"]; 
     //a.pinColor=[UIColor redColor]; 
    } 
    else 
    { 

     // annView.image =[UIImage imageNamed:@"map-pin.png"]; 
     //PinFirst=FALSE; 
     //annView.pinColor = [UIColor redColor]; 
     // annView.annotation=annotation; 
    } 

    annView.animatesDrop = YES; 
    annView.draggable = YES; 

    annView.canShowCallout = YES; 

    return annView; 
} 

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 
{ 
    NSLog(@"map Drag"); 
} 

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState 
fromOldState:(MKAnnotationViewDragState)oldState; 
{ 
    NSLog(@"pin Drag"); 

    if (newState == MKAnnotationViewDragStateEnding) 
    { 
     CLLocationCoordinate2D droppedAt = view.annotation.coordinate; 
     NSLog(@"Pin dropped at %f,%f", droppedAt.latitude, droppedAt.longitude); 

     CLLocation* draglocation = [[[CLLocation alloc] initWithLatitude:droppedAt.latitude longitude:droppedAt.longitude] autorelease]; 



    } 
} 
+0

Gracias por tal como la solución completa –

0

Ejemplo de Swift 2.2, Xcode 7.3.1:

  • Crear clase personalizada adopción del protocolo MKAnnotation

    (nota: Swift no lo hace tiene una notificación automática para las propiedades que cumplen con KVO, así que he agregado la mía - esto no es obligatorio):

    import MapKit 
    
    class MyAnnotation: NSObject, MKAnnotation { 
    
        // MARK: - Required KVO-compliant Property 
        var coordinate: CLLocationCoordinate2D { 
         willSet(newCoordinate) { 
          let notification = NSNotification(name: "VTAnnotationWillSet", object: nil) 
          NSNotificationCenter.defaultCenter().postNotification(notification) 
         } 
    
         didSet { 
          let notification = NSNotification(name: "VTAnnotationDidSet", object: nil) 
          NSNotificationCenter.defaultCenter().postNotification(notification) 
         } 
        } 
    
    
        // MARK: - Required Initializer 
        init(coordinate: CLLocationCoordinate2D) { 
         self.coordinate = coordinate 
        } 
    } 
    
  • Declarar pin vista como desplazable:

    // MARK: - MKMapViewDelegate Actions 
    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { 
    
        let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: pinViewReuseIdentifier) 
        pinView.draggable = true 
    
        return pinView 
    } 
    

Ahora, cuando se arrastra el pasador, se invoca el método delegado:

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) 

Aquí, se puede recuperar las nuevas coordenadas finales.


Como alternativa, puede crear un diccionario para las notificaciones userInfocoordinate de propiedad de la anotación personalizada. Los observadores podrían recuperar los valores una vez recibida la notificación.

0

En Swift mi problema era que el atributo coordinate era un let en mi subclase y no un var como lo es en la MKAnnotation.

class MyAnnotation : NSObject, MKAnnotation { 

    let title  : String? 
    let subtitle : String? 
    var coordinate : CLLocationCoordinate2D 

    init(title: String, subtitle: String, coordinate: CLLocationCoordinate2D) { 
     self.title = title 
     self.subtitle = subtitle 
     self.coordinate = coordinate 
     super.init() 
    } 
} 
Cuestiones relacionadas