2013-03-08 16 views
40

Ho un elenco di annotazioni (MKPointAnnotation). Ho un UIViewController che è per l'intera vista, MKMapView che implementa Controller, che ho ritenuto utile per rilevare l'interazione dell'utente con la mappa, il mio MKPointAnnotation che implementa (sottoclasse) Controller che indica come mostrare l'annotazione.MKMapView MKPointAnnotazione evento tap

Tuttavia sono colpito dal rilevamento dell'evento di tocco da parte dell'utente.

Googling mi ha detto che devo fare qualcosa implementando la seguente funzione.

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 

e anche che devo implementarlo in qualche classe che implementa il MapViewDelegate (Protocollo).

Ma sono tutto confuso e incapace di andare avanti. Qualcuno può dirmi dove fare cosa?

Ci scusiamo per il trambusto!

+0

è necessario impostare i tag per ciascuna annotazione, in modo che quando si tocca qualsiasi annotazione è possibile ottenere l'etichetta di ritorno da annotazioni e chiamare il rispettivo membro di dati dell'array generare queste annotazioni. – yunas

+0

- (vuoto) mapView: (MKMapView *) mapView annotationView: (MKAnnotationView *) visualizza calloutAccessoryControlTapped: (Controllo UIControl *) { NSLog (@ "got here"); } ..... Ho inserito questa funzione in tutti e tre i controller ma nessuno di essi viene chiamato .... puoi dirmi dove dovrei definire questa funzione? –

risposta

95

Ci sono due modi per rilevare l'interazione dell'utente con il tuo vista annotazione. La tecnica comune è definire un callout (quella bolla standard popover che si vede quando si tocca un pin in un'applicazione di mappe tipica) per il proprio MKAnnotationView. E si crea la vista annotazione per l'annotazione nel metodo standard viewForAnnotation:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
{ 
    if ([annotation isKindOfClass:[MKUserLocation class]]) 
     return nil; 

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"]; 
    annotationView.canShowCallout = YES; 
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 

    return annotationView; 
} 

In questo modo, si ottiene un richiamo, ma si sta aggiungendo un accessorio destra, che è, a mio esempio di cui sopra, una rivelazione indicatore. In questo modo, toccano la vista annotazione (nell'esempio precedente, un segnaposto sulla mappa), visualizzano il callout e quando toccano l'accessorio giusto di quel callout (il piccolo indicatore di divulgazione in questo esempio), viene chiamato il tuo calloutAccessoryControlTapped (nel mio esempio qui di seguito, l'esecuzione di un segue a qualche controllore vista di dettaglio):

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 
{ 
    [self performSegueWithIdentifier:@"DetailsIphone" sender:view]; 
} 

Questa è un'esperienza utente molto tipico sul piccolo schermo di iPhone.

Ma se non ti piace UX e non vuoi il callout standard, ma vuoi che succeda qualcos'altro, puoi definire il tuo MKAnnotationView in modo che non venga mostrato un callout, ma invece intercetti e fa qualcos'altro (ad esempio, nelle app di mappe di iPad, potresti mostrare un popover più sofisticato piuttosto che il callout standard). Ad esempio, si potrebbe avere il MKAnnotationView non mostrano una didascalia:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
{ 
    if ([annotation isKindOfClass:[MKUserLocation class]]) 
     return nil; 

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"]; 
    annotationView.canShowCallout = NO; 

    return annotationView; 
} 

Ma si può quindi gestire manualmente didSelectAnnotationView per rilevare quando un utente batté sul MKAnnotationView, in questo esempio che mostra una popover:

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view 
{ 
    [mapView deselectAnnotation:view.annotation animated:YES]; 

    DetailsViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailsPopover"]; 
    controller.annotation = view.annotation; 
    self.popover = [[UIPopoverController alloc] initWithContentViewController:controller]; 
    self.popover.delegate = self; 
    [self.popover presentPopoverFromRect:view.frame 
            inView:view.superview 
       permittedArrowDirections:UIPopoverArrowDirectionAny 
           animated:YES]; 
} 

Includo alcune istantanee dello schermo per l'interfaccia utente fornite dal codice sopra riportato in my answer here.

+0

Ciao, Questo non sembra funzionare per iOS7 e fino. Qualche suggerimento per una correzione per iOS8? – roshi

+0

@roshi L'ho provato e funziona perfettamente con iOS 8. Hai impostato il delegato della visualizzazione della mappa? Se hai ancora problemi, puoi pubblicare la tua domanda su S.O. con esempi di codice dettagliati, descrizione di ciò che hai provato, ecc. – Rob

+0

@Rob Puoi dare un'occhiata a http://stackoverflow.com/questions/30396754/ios-custom-annotation-a-view-below-the -notation-pin & aiutami a risolvere il mio problema – iYoung

3

pulsante Aggiungi in questo metodo

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
{ 
    pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
    pinView.canShowCallout = YES; 
} 

Then callout method 
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 
{ 
     InfoView *infoView = [[InfoView alloc]initWithNibName:@"InfoView" bundle:nil]; 
     [self.navigationController pushViewController:infoView animated:YES]; 

} 
+0

Puoi dirmi dove dovrei implementarli? MKMapView Controller? –

+0

@RaviVooda yaa Sono imposti sulla codifica di MapViewpart. qualsiasi altro problema puoi chiedermelo :) – Bajaj

+0

@RaviVooda Dovresti implementarli nel 'delegato' per il tuo' MKMapView'. Spesso designate il 'delegato' per' MKMapView' come controller di visualizzazione per la vista che ha la vista mappa su di esso. Ma non dimenticare di impostare il delegato della vista mappa (nel codice o tramite Interface Builder). – Rob

4

deruba esempio per Swift 3:

class MapViewController: UIViewController 
{ 
    override func viewDidLoad() 
    { 
     super.viewDidLoad() 

     // Create map view in storyboard 
     view.delegate = self 
    } 
} 

extension MapViewController: MKMapViewDelegate 
{ 
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? 
    { 
     let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotationView") 
     annotationView.canShowCallout = true 
     annotationView.rightCalloutAccessoryView = UIButton.init(type: UIButtonType.detailDisclosure) 

     return annotationView 
    } 

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) 
    { 
     guard let annotation = view.annotation else 
     { 
      return 
     } 

     let urlString = "http://maps.apple.com/?sll=\(annotation.coordinate.latitude),\(annotation.coordinate.longitude)" 
     guard let url = URL(string: urlString) else 
     { 
      return 
     } 

     UIApplication.shared.openURL(url) 
    } 
}