2015-05-05 13 views
6

Moja aplikacja ma obecnie lokalne wyszukiwanie, które dodaje adnotacje do wyników wyszukiwania. Chcę go ustawić w miejscu, w którym po wybraniu adnotacji i kliknięciu przycisku wywołania otworzy się w aplikacji Mapy ze wskazówkami dotyczącymi adnotacji z aktualnej lokalizacji urządzenia. Mam z tym kilka problemów.Swift - wskazówki do wybranych adnotacji z bieżącej lokalizacji w Mapach

Po pierwsze, przycisk wezwania na adnotacji nie pojawia się. Po drugie, nie sądzę, abym poprawnie wykrył wybraną adnotację.

Oto mój kod do wyszukiwania i wybranej adnotacji:

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

} 

Każda pomoc będzie mile widziane, z góry dzięki.

Odpowiedz

6

Na pierwszym numerze: przycisk

objaśnienie musi być ustawione wyraźnie w sposobie viewForAnnotation delegata (domyślne czerwone szpilki nie masz). Oto prosty przykład jednej z możliwych realizacji:

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 
} 


Na drugim numerze:

pierwsze, w calloutAccessoryControlTapped, adnotacji jest dostępny bezpośrednio za pomocą view.annotation więc przy użyciu tablicy selectedAnnotations tam jest niepotrzebna .

Następnie openMapsWithItems spodziewa tablicę MKMapItem obiektów, ale w tablicy są przechodzącą ([selectedLoc, currentLoc]) selectedLoc jest nieMKMapItem - to tylko niektóre obiekt, który implementuje MKAnnotation.

Uruchomienie tego kodu spowoduje awarii z tego błędu:

-[MKPointAnnotation dictionaryRepresentation]: unrecognized selector sent to instance

gdy aplikacja Mapy próbuje użyć selectedLoc jakby to był MKMapItem.

Zamiast tego należy utworzyć MKMapItem z adnotacji selectedLoc. Można to zrobić, najpierw tworząc MKPlacemark z adnotacji przy użyciu MKPlacemark(coordinate:addressDictionary:), a następnie tworząc MKMapItem z oznaczenia miejsca przy użyciu MKMapItem(placemark:).

Przykład:

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

Jakoś downvoted tę odpowiedź, nie wiedząc nawet (ktoś bawił się z moim telefonem). Przepraszam za to. Teraz nie mogę tego cofnąć. Jeśli chcesz, możesz edytować, więc mogę to zmienić. –

+1

@flashadvanced: Nie ma problemu, dziękuję za wyjaśnienie tego. – Anna

+0

Dziękuję bardzo za pomoc! Moje ostatnie pytanie to ... Jak mogę przypisać widok do utworzonych adnotacji w 'performSearch()'? Po dodaniu kodu i uruchomieniu widok adnotacji nadal jest domyślną czerwoną pinezką. – Alec

Powiązane problemy