Я хочу добавить аннотацию на сенсорную карту iOS и получить подробный адрес (метки) соответствующего местоположения. Как я могу достичь этого в Swift?
Спасибо заранее.
Я хочу добавить аннотацию на сенсорную карту iOS и получить подробный адрес (метки) соответствующего местоположения. Как я могу достичь этого в Swift?
Спасибо заранее.
Чтобы реагировать на касание на карте, вам нужно настроить распознаватель крана для mapView
в viewDidLoad
:
let gestureRecognizer = UITapGestureRecognizer(target: self, action:"handleTap:")
gestureRecognizer.delegate = self
mapView.addGestureRecognizer(gestureRecognizer)
Обращайтесь с краном и получим координаты местоположения:
func handleTap(gestureReconizer: UILongPressGestureRecognizer) {
let location = gestureReconizer.locationInView(mapView)
let coordinate = mapView.convertPoint(location,toCoordinateFromView: mapView)
// Add annotation:
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
mapView.addAnnotation(annotation)
}
Теперь вам нужно реализовать функции делегата MKMapView для рисования аннотаций. Простой поисковый запрос google должен предоставить вам остальную часть этого.
Вот рабочий проект Xcode 10.1, Swift 4.2 с делегатами MapKit для управления аннотациями (цвет пин- кода, изображение пин- кода и т.д.) И делегатом для обработки щелчка по добавленной аннотации: Github Project
import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
let longTapGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap))
mapView.addGestureRecognizer(longTapGesture)
}
@objc func longTap(sender: UIGestureRecognizer){
print("long tap")
if sender.state == .began {
let locationInView = sender.location(in: mapView)
let locationOnMap = mapView.convert(locationInView, toCoordinateFrom: mapView)
addAnnotation(location: locationOnMap)
}
}
func addAnnotation(location: CLLocationCoordinate2D){
let annotation = MKPointAnnotation()
annotation.coordinate = location
annotation.title = "Some Title"
annotation.subtitle = "Some Subtitle"
self.mapView.addAnnotation(annotation)
}
}
extension ViewController: MKMapViewDelegate{
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard annotation is MKPointAnnotation else { print("no mkpointannotaions"); return nil }
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.rightCalloutAccessoryView = UIButton(type: .infoDark)
pinView!.pinTintColor = UIColor.black
}
else {
pinView!.annotation = annotation
}
return pinView
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
print("tapped on pin ")
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if control == view.rightCalloutAccessoryView {
if let doSomething = view.annotation?.title! {
print("do something")
}
}
}
}
Свифт 4:
@IBOutlet weak var mapView: MKMapView!
func handleLongPress (gestureRecognizer: UILongPressGestureRecognizer) {
if gestureRecognizer.state == UIGestureRecognizerState.began {
let touchPoint: CGPoint = gestureRecognizer.location(in: mapView)
let newCoordinate: CLLocationCoordinate2D = mapView.convert(touchPoint, toCoordinateFrom: mapView)
addAnnotationOnLocation(pointedCoordinate: newCoordinate)
}
}
func addAnnotationOnLocation(pointedCoordinate: CLLocationCoordinate2D {
let annotation = MKPointAnnotation()
annotation.coordinate = pointedCoordinate
annotation.title = "Loading..."
annotation.subtitle = "Loading..."
mapView.addAnnotation(annotation)
}
Для быстрого 3.0
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
gestureRecognizer.delegate = self
mapView.addGestureRecognizer(gestureRecognizer)
func handleTap(_ gestureReconizer: UILongPressGestureRecognizer) {
let location = gestureReconizer.locationInView(mapView)
let coordinate = mapView.convertPoint(location,toCoordinateFromView: mapView)
// Add annotation:
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
mapView.addAnnotation(annotation)
}
Для Swift 4 я конвертировал пример Swift 3, так как другой Swift 4 у меня не работал: (обратите внимание, что я использую "mapview" вместо "mapView" просто для соответствия другому коду
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
gestureRecognizer.delegate = self
mapview.addGestureRecognizer(gestureRecognizer)
@objc func handleTap(_ gestureReconizer: UILongPressGestureRecognizer)
{
let location = gestureReconizer.location(in: mapview)
let coordinate = mapview.convert(location,toCoordinateFrom: mapview)
// Add annotation:
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
mapview.addAnnotation(annotation)
}
Поскольку другие ответы адекватно описывают, как обрабатывать событие касания, следующим шагом будет использование CLGeocoder
для предварительной обработки обратного геокодирования, которое преобразует значение местоположения в список меток в этом месте.
func handleTap(gestureReconizer: UILongPressGestureRecognizer) {
let location = gestureReconizer.locationInView(mapView)
let coordinate = mapView.convertPoint(location,toCoordinateFromView: mapView)
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(coordinate) { (placemarks, error) in
if let places = placemarks {
for place in places {
print("found placemark \(place.name) at address \(place.postalAddress)"
}
}
}
}