iOS:Swift - 如何在触摸地图上添加精确定位并获取该位置的详细地址?
Posted
技术标签:
【中文标题】iOS:Swift - 如何在触摸地图上添加精确定位并获取该位置的详细地址?【英文标题】:iOS : Swift - How to add pinpoint to map on touch and get detailed address of that location? 【发布时间】:2016-03-29 15:20:49 【问题描述】:我想在触摸 ios 地图时添加注释并获取相应位置的详细地址(地标)。我如何在 Swift 中实现这一点?
提前致谢。
【问题讨论】:
他特别提到了“地标”。我发现这篇文章是因为我正在寻找如何从注释中获取地标。我很高兴这个线程会回答这个问题,因为这就是 OP 所要求的。但是,无论如何,一个只解决了一半问题的答案不能被认为是完整的。 使用这个 -> github.com/almassapargali/LocationPicker 【参考方案1】:要对地图上的触摸做出反应,您需要为 mapView 设置一个点击识别器
在viewDidLoad
:
let gestureRecognizer = UITapGestureRecognizer(
target: self, action:#selector(handleTap))
gestureRecognizer.delegate = self
mapView.addGestureRecognizer(gestureRecognizer)
处理点击并获取点击位置坐标:
func handleTap(gestureRecognizer: UITapGestureRecognizer)
let location = gestureRecognizer.location(in: mapView)
let coordinate = mapView.convert(location, toCoordinateFrom: mapView)
// Add annotation:
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
mapView.addAnnotation(annotation)
现在您只需实现 MKMapView 委托函数即可绘制注释。一个简单的谷歌搜索应该让你得到剩下的。
【讨论】:
我为 swift 3 @Neo42 添加了一个编辑。一旦经过同行评审,您就可以看到它 这个“答案”不回答用户的问题。 OP 询问如何获得地标。 除非没有其他选项,否则您永远不应使用字符串文字来标识选择器。相反,请使用#selector(handleTap(gestureRecognizer:))
。这可以防止拼写错误并允许您使用 Xcode 的重构工具。【参考方案2】:
//put this in 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)
locationManager.stopUpdatingLocation();
print("the location lattitude is = \(locationOnMap.latitude) and logitude on map = \(locationOnMap.longitude)")
self.passlat = Double(locationOnMap.latitude)
self.passlong = Double(locationOnMap.longitude)
self.getAddressFromLatLon(pdblLatitude: "\(locationOnMap.latitude)", withLongitude: "\(locationOnMap.longitude)")
func getAddressFromLatLon(pdblLatitude: String, withLongitude pdblLongitude: String)
var center : CLLocationCoordinate2D = CLLocationCoordinate2D()
let lat: Double = Double("\(pdblLatitude)")!
//21.228124
let lon: Double = Double("\(pdblLongitude)")!
//72.833770
let ceo: CLGeocoder = CLGeocoder()
center.latitude = lat
center.longitude = lon
let loc: CLLocation = CLLocation(latitude:center.latitude, longitude: center.longitude)
ceo.reverseGeocodeLocation(loc, completionHandler:
(placemarks, error) in
if (error != nil)
print("reverse geodcode fail: \(error!.localizedDescription)")
let pm = placemarks! as [CLPlacemark]
if pm.count > 0
let pm = placemarks![0]
// print(pm.country)
//print(pm.locality)
self.mapaddcontry = pm.country!
self.mapaddrState = pm.subLocality!
self.mapaddrcity = pm.locality!
self.mapaddrPincode = pm.postalCode!
self.mainname = pm.locality!
print(pm.subLocality)
self.subname = pm.subLocality!
print(pm.thoroughfare)
print(pm.postalCode)
print(pm.subThoroughfare)
var addressString : String = ""
if pm.subLocality != nil
addressString = addressString + pm.subLocality! + ", "
if pm.thoroughfare != nil
addressString = addressString + pm.thoroughfare! + ", "
if pm.locality != nil
addressString = addressString + pm.locality! + ", "
if pm.country != nil
addressString = addressString + pm.country! + ", "
if pm.postalCode != nil
addressString = addressString + pm.postalCode! + " "
self.addr.text = addressString
print(addressString)
self.mapaddrtxt.text = addressString
self.location_name = addressString
)
【讨论】:
@anurag mkmapView.addAnnotation(locationOnMap as!MKAnnotation) 出现错误无法将“__C.CLLocationCoordinate2D”(0x10c801f88)类型的值转换为“__C.MKAnnotation”(0x7fd45a94e6c8)。【参考方案3】:由于其他答案充分涵盖了如何处理触摸事件,下一步是使用 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)"
【讨论】:
【参考方案4】:这是一个有效的 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")
【讨论】:
这个“答案”不回答用户的问题。 OP 询问如何获得地标。 请再仔细阅读问题,然后再想一想。问题是如何在触摸时添加注释并获取地址。我的回答涵盖了其中的 50%。仅仅因为它没有回答你的问题,并不意味着它是错误的。 引用 OP:“...获取详细地址(地标)”,他要求的是地标。 不,但看起来你是。是的,他要求两件事:放置注释和获取地标,而不仅仅是详细地址。没有一个答案可以解决地标问题。部分答案的部分功劳。 顺便说一句,我从来没有说过你的答案是错误的。但 50% 的答案不是答案。如果有人问我从柏林到法兰克福的路线,我说:“走到街的尽头,左转”,我几乎不会因为回答最初的问题而受到鼓掌。【参考方案5】:对于 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)
【讨论】:
这个“答案”不回答用户的问题。 OP 询问如何获得地标。【参考方案6】:斯威夫特 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)
【讨论】:
这个“答案”不回答用户的问题。 OP 询问如何获得地标。【参考方案7】:对于 swift 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)
【讨论】:
这个“答案”不回答用户的问题。 OP 询问如何获得地标。以上是关于iOS:Swift - 如何在触摸地图上添加精确定位并获取该位置的详细地址?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Ti.map 上的苹果地图上添加“当前位置按钮”(导航标记)