2015-05-05 8 views
6

La mia app dispone attualmente di una ricerca locale che aggiunge annotazioni per i risultati della ricerca. Voglio impostarlo dove, quando selezioni l'annotazione e fai clic sul pulsante di chiamata, si aprirà nell'applicazione Maps con le indicazioni per l'annotazione dalla posizione corrente del dispositivo. Sto avendo qualche problema con questo.Swift - Indicazioni per l'annotazione selezionata dalla posizione corrente in Maps

Prima di tutto, il pulsante di chiamata sull'annotazione non viene visualizzato. In secondo luogo, non penso di rilevare correttamente l'annotazione selezionata.

Ecco il mio codice per la ricerca e la scelta della nota:

func performSearch() { 

    matchingItems.removeAll() 
    let request = MKLocalSearchRequest() 
    request.naturalLanguageQuery = searchText.text 
    request.region = mapView.region 

    let search = MKLocalSearch(request: request) 

    search.startWithCompletionHandler({(response: 
     MKLocalSearchResponse!, 
     error: NSError!) in 

     if error != nil { 
      println("Error occured in search: \(error.localizedDescription)") 
     } else if response.mapItems.count == 0 { 
      println("No matches found") 
     } else { 
      println("Matches found") 

      for item in response.mapItems as! [MKMapItem] { 
       println("Name = \(item.name)") 
       println("Phone = \(item.phoneNumber)") 

       self.matchingItems.append(item as MKMapItem) 
       println("Matching items = \(self.matchingItems.count)") 

       var annotation = MKPointAnnotation() 
       var coordinates = annotation.coordinate 
       annotation.coordinate = item.placemark.coordinate 
       annotation.title = item.name 
       self.mapView.addAnnotation(annotation) 

      } 
     } 
    }) 
} 



func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, 
    calloutAccessoryControlTapped control: UIControl!) { 

     if self.mapView.selectedAnnotations?.count > 0 { 

      if let selectedLoc = self.mapView.selectedAnnotations[0] as? MKAnnotation { 
       println("Annotation has been selected") 
       let currentLoc = MKMapItem.mapItemForCurrentLocation() 
       let mapItems = NSArray(objects: selectedLoc, currentLoc) 
       let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] 
       MKMapItem.openMapsWithItems([selectedLoc, currentLoc], launchOptions: launchOptions) 
      } 
     } 

} 

Qualsiasi aiuto sarà apprezzato, grazie in anticipo.

risposta

6

Per il primo numero: pulsante

Un richiamo deve essere impostato in modo esplicito nel metodo viewForAnnotation delegato (rosso predefinite pin non hanno uno). Ecco un semplice esempio di una possibile implementazione:

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! { 

    if annotation is MKUserLocation { 
     return nil 
    } 

    let reuseId = "pin" 

    var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView 
    if pinView == nil { 
     pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId) 
     pinView!.canShowCallout = true 
     pinView!.pinColor = .Purple 

     //next line sets a button for the right side of the callout... 
     pinView!.rightCalloutAccessoryView = UIButton.buttonWithType(.DetailDisclosure) as! UIButton 
    } 
    else { 
     pinView!.annotation = annotation 
    } 

    return pinView 
} 


Per il secondo problema:

primo luogo, nel calloutAccessoryControlTapped, l'annotazione è direttamente accessibile tramite view.annotation quindi utilizzando la matrice selectedAnnotations in c'è inutile .

Avanti, openMapsWithItems si aspetta un array di oggetti MKMapItem ma nella matrice si sta passando ([selectedLoc, currentLoc]), selectedLoc non è un MKMapItem - è solo un oggetto che implementa MKAnnotation.

L'esecuzione di questo codice si tradurrà in un incidente con questo errore:

-[MKPointAnnotation dictionaryRepresentation]: unrecognized selector sent to instance

quando l'applicazione Maps cerca di utilizzare selectedLoc come se fosse un MKMapItem.

Invece, è necessario creare un MKMapItem dall'annotazione selectedLoc. Questo può essere fatto creando prima un MKPlacemark dall'annotazione utilizzando MKPlacemark(coordinate:addressDictionary:) e creando quindi un MKMapItem dal segnaposto utilizzando MKMapItem(placemark:).

Esempio:

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, 
    calloutAccessoryControlTapped control: UIControl!) { 

     let selectedLoc = view.annotation 

     println("Annotation '\(selectedLoc.title!)' has been selected") 

     let currentLocMapItem = MKMapItem.mapItemForCurrentLocation() 

     let selectedPlacemark = MKPlacemark(coordinate: selectedLoc.coordinate, addressDictionary: nil) 
     let selectedMapItem = MKMapItem(placemark: selectedPlacemark) 

     let mapItems = [selectedMapItem, currentLocMapItem] 

     let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] 

     MKMapItem.openMapsWithItems(mapItems, launchOptions:launchOptions) 
} 
+1

In qualche modo ho downvoted questa risposta senza nemmeno sapere (qualcuno stava giocando con il mio telefono). Mi scuso per quello. Ora non posso annullare. Se vuoi puoi fare una modifica in modo da poterlo ripristinare. –

+1

@flashadvanced: Nessun problema, grazie per averlo spiegato. – Anna

+0

Grazie mille per l'aiuto! La mia ultima domanda è ... Come posso assegnare la vista alle annotazioni create in 'performSearch()'? Dopo aver aggiunto il codice ed eseguito, la vista di annotazione è ancora il pin rosso predefinito. – Alec

Problemi correlati