Swift - направления к выбранной аннотации из текущего местоположения на картах

Мое приложение в настоящее время имеет локальный поиск, который добавляет аннотации к результатам поиска. Я хочу указать, где, когда вы выбираете аннотацию и нажимаете кнопку вызова, она открывается в приложении "Карты" с указаниями к аннотации из текущего местоположения устройства. У меня есть несколько проблем с этим.

Прежде всего, моя кнопка вызова на аннотации не появляется. Во-вторых, я не думаю, что правильно определяю выбранную аннотацию.

Вот мой код для поиска и выбранной аннотации:

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

}

Любая помощь будет оценена, спасибо заранее.

1 ответ

Решение

Для первого номера:

Кнопка выноски должна быть явно установлена ​​в viewForAnnotation метод делегата (по умолчанию красные контакты не имеют такового). Вот простой пример одной возможной реализации:

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
}


Для второго выпуска:

Первый в calloutAccessoryControlTappedаннотация доступна напрямую с помощью view.annotation так что используя selectedAnnotations массив там не нужен.

Следующий, openMapsWithItems ожидает массив MKMapItem объекты, но в массиве вы передаете ([selectedLoc, currentLoc]), selectedLoc это не MKMapItem - это просто какой-то объект, который реализует MKAnnotation,

Выполнение этого кода приведет к падению с этой ошибкой:

- [MKPointAnnotation dictionaryRepresentation]: нераспознанный селектор отправлен на экземпляр

когда приложение Карты пытается использовать selectedLoc как будто это было MKMapItem,

Вместо этого вам нужно создать MKMapItem от selectedLoc аннотаций. Это можно сделать, сначала создав MKPlacemark из аннотации с использованием MKPlacemark(coordinate:addressDictionary:) а затем создание MKMapItem от метки с помощью MKMapItem(placemark:),

Пример:

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)
}
Другие вопросы по тегам