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