2010-08-03 16 views
22

Estoy trabajando con MKMapView y MKAnnotationView.Detectar Tap en CalloutBubble en MKAnnotationView

Tengo una anotación en el mapa. Cuando los usuarios tocan sobre él, se muestra la burbuja callOut. Cuando se vuelve a tocar la anotación (y callOut Bubble está visible), necesito cambiar a otra vista.

¿Cómo puedo detectar el segundo toque o el toque en la burbuja?

+0

¿Ha encontrado la solución? –

+3

La manera más simple es establecer un botón como el derecho de acceso de pantalla e implementar calloutAccessoryControlTapped. ¿No es eso suficiente o debes aprovechar el título y el subtítulo también? – Anna

Respuesta

10

¿Podría agregar un reconocedor de gestos al inicializar el MKAnnotationView?

Aquí está el código para el interior dequeueReusableAnnotationViewWithIdentifier:

UITapGestureRecognizer *tapGesture = 
     [[UITapGestureRecognizer alloc] initWithTarget:self 
             action:@selector(calloutTapped:)]; 
[theAnnotationView addGestureRecognizer:tapGesture]; 
[tapGesture release]; 

El método para el reconocedor gesto:

-(void) calloutTapped:(id) sender { 
    // code to display whatever is required next. 

    // To get the annotation associated with the callout that caused this event: 
    // id<MKAnnotation> annotation = ((MKAnnotationView*)sender.view).annotation; 
} 
+4

La llamada no es lo mismo que la vista de anotación. La llamada es la burbuja que aparece cuando toca la vista del texto destacado. – shim

+6

Agregué el gestureRecognizer en el método mapView: didSelectAnnotationView: y esta solución funcionó perfectamente para mí. –

+0

@DanielT. Usted, el MVP: P –

6

tocar el botón de llamada después de que el usuario ha hecho clic en la vista de anotación, añadir un UITapGestureRecognizer en didSelectAnnotationView. De esta forma puede implementar el toque en la llamada sin necesitar las vistas de accesorios.

A continuación, puede recuperar el objeto de anotación del remitente para realizar otras acciones.

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view 
{ 
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(calloutTapped:)]; 
    [view addGestureRecognizer:tapGesture]; 
} 

-(void)calloutTapped:(UITapGestureRecognizer *) sender 
{ 
    NSLog(@"Callout was tapped"); 

    MKAnnotationView *view = (MKAnnotationView*)sender.view; 
    id <MKAnnotation> annotation = [view annotation]; 
    if ([annotation isKindOfClass:[MKPointAnnotation class]]) 
    { 
     [self performSegueWithIdentifier:@"annotationDetailSegue" sender:annotation]; 
    } 
} 
+2

Tenga cuidado con esta solución. El problema aquí es que creas un gesto de toque cada vez que seleccionas una anotación para que tengas problemas con la creación de múltiples toques, por ejemplo, si la seleccionas, la anulas y la vuelves a seleccionar. Creo que es mejor agregar un gesto de tap en la inicialización de AnnotationView o manejar la eliminación de gestos en deselection – Beninho85

4

intenta establecer la imagen personalizada para el botón sin necesidad de cambiar el tipo UIButtonTypeDetailDisclosure.

UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];   
[detailButton setImage:[UIImage imageNamed:@"icon"] forState:UIControlStateNormal]; 
+1

¡Bonito! Es triste que cosas como esta no estén documentadas en ninguna parte de las API -.- – Cabus

6

Aquí está la versión rápida de la respuesta de Dhanu, incluyendo la obtención de los datos del elemento seleccionado para pasar a la siguiente controlador de vista:

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) { 
    let gesture = UITapGestureRecognizer(target: self, action: #selector(MyMapViewController.calloutTapped(_:))) 
    view.addGestureRecognizer(gesture) 
} 

func calloutTapped(sender:UITapGestureRecognizer) { 
    guard let annotation = (sender.view as? MKAnnotationView)?.annotation as? MyAnnotation else { return } 

    selectedLocation = annotation.myData 
    performSegueWithIdentifier("mySegueIdentifier", sender: self) 
} 
0

Swift 3, utilizando On. Necesita manejar rightCalloutAccessoryView

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 
    switch annotation { 
    case let annotation as Annotation: 
    let view: AnnotationView = mapView.dequeue(annotation: annotation) 
    view.canShowCallout = true 
    let button = UIButton(type: .detailDisclosure) 
    button.on.tap { [weak self] in 
     self?.handleTap(annotation: annotation) 
    } 
    view.rightCalloutAccessoryView = button 
    return view 
    default: 
    return nil 
    } 
} 
Cuestiones relacionadas