ios - 更新 MapView 引脚位置
问题描述
所以我有一个 MapView,它向当前用户位置添加了一个 pin。我也有两个文本字段,显示图钉的坐标。我想添加两个功能:
当我拖放图钉时,我想更新文本字段内的坐标。
当我在文本字段中编辑坐标时,它应该将大头针从文本字段移动到更新的坐标。
这是我的代码,我在其中处理 MapView 的所有内容。我对编码还是很陌生,所以代码可能会令人困惑,对此感到抱歉。
class LocateVC: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var finishedLocateButton: UIButton!
@IBOutlet weak var relocateButton: UIButton!
var coordinates: [[Double]]!
var latTitleLabel:[String]!
var latValueLabel:[String]!
var lngTitleLabel:[String]!
var lngValueLabel: [String]!
var isEdited = false
var customCallout: UIView?
//Important to track location
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
view.layer.backgroundColor = Colors.grey.cgColor
//button titles
relocateButton.isHidden = true
relocateButton.setTitle("Relocate", for: .normal)
finishedLocateButton.setTitle("Continue", for: .normal)
navigationItem.title = "Location"
// Ask for Authorisation from the User.
self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()
locationManager.delegate = self
self.mapView.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
if isEdited == false {
if CLLocationManager.locationServicesEnabled() {
addPin()
}
}
// Latitude,Longitude
coordinates = [
[ProductData.shared.latitude!, ProductData.shared.longitude!],
]
} //end of viewDidLoad
override func viewWillAppear(_ animated: Bool) {
super.dismiss(animated: animated)
}
public func removePin() {
}
func dropPinFor(placemark: MKPlacemark) {
for annotation in mapView.annotations {
if annotation.isKind(of: MKPointAnnotation.self) {
// mapView.removeAnnotation(annotation) // removing the pins from the map
}
}
let annotation = MKPointAnnotation()
annotation.coordinate = placemark.coordinate
mapView.addAnnotation(annotation)
}
//1
public func addPin() {
if isEdited == false {
ProductData.shared.latitude = locationManager.location?.coordinate.latitude
ProductData.shared.longitude = locationManager.location?.coordinate.longitude
}
self.mapView.delegate = self
// adds an annotation to coordinates from productData
let point = ProductAnnotation(coordinate: CLLocationCoordinate2D(latitude: ProductData.shared.latitude! , longitude: ProductData.shared.longitude!))
self.mapView.addAnnotation(point)
// 3
let region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: ProductData.shared.latitude!, longitude: ProductData.shared.longitude!), span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))
self.mapView.setRegion(region, animated: true)
}
public func editCoord() {
performSegue(withIdentifier: "editCoord", sender: CustomCalloutView.self)
}
@IBAction func relocateButtonClicked(_ sender: Any) {
addPin()
}
@IBAction func finishedLocateButtonClicked(_ sender: Any) {
performSegue(withIdentifier: "finishedLocateSegue2", sender: self)
}
//4
func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
if view.isKind(of: CustomCalloutView.self ) || view.isKind(of: AnnotationView.self) || view.isKind(of: ProductAnnotation.self) {
return
} else {
customCallout?.removeFromSuperview()
}
}
//3
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
if view.annotation is MKUserLocation {
return
}
//this creates the callout
let views = Bundle.main.loadNibNamed("CustomCalloutView", owner: nil, options: nil)
let calloutView = views?[0] as! CustomCalloutView
calloutView.delegate = self
calloutView.lngTitleLabel.text = "Lng"
calloutView.latTitleLabel.text = "Lat"
calloutView.lngTextField.text = String(format:"%f", ProductData.shared.longitude!)
calloutView.latTextField.text = String(format:"%f", ProductData.shared.latitude!)
calloutView.latTextField.layer.borderWidth = 0.0
calloutView.lngTextField.layer.borderWidth = 0.0
calloutView.latTextField.isEnabled = false
calloutView.lngTextField.isEnabled = false
calloutView.latTextField.keyboardType = .numberPad
calloutView.lngTextField.keyboardType = .numberPad
calloutView.alpha = 1.0
calloutView.layer.cornerRadius = 8
calloutView.center = CGPoint(x: view.bounds.size.width / 2, y: -calloutView.bounds.size.height*0.52)
customCallout = calloutView
view.addSubview(calloutView)
mapView.setCenter((view.annotation?.coordinate)!, animated: true)
}
//2
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
var annotationView = self.mapView.dequeueReusableAnnotationView(withIdentifier: "Pin")
if annotationView == nil{
annotationView = AnnotationView(annotation: annotation, reuseIdentifier: "Pin")
annotationView?.isDraggable = true
annotationView?.canShowCallout = false
} else {
annotationView?.annotation = annotation
}
annotationView?.image = UIImage(named: "dot")
return annotationView
}
func saveButtonTapped() {
customCallout?.removeFromSuperview()
}
}
extension LocateVC: CustomCalloutViewDelegate {
func didClickEditButton() {
editCoord()
}
func didClickSaveButton() {
saveButtonTapped()
}
}
这里是我的自定义标注:
class CustomCalloutView: UIView {
@IBOutlet weak var latTitleLabel: UILabel!
@IBOutlet weak var lngTitleLabel: UILabel!
@IBOutlet weak var editButton: UIButton!
@IBOutlet weak var saveButton: UIButton!
@IBOutlet weak var latTextField: UITextField!
@IBOutlet weak var lngTextField: UITextField!
var delegate: CustomCalloutViewDelegate?
var isEditing: Bool = false
@IBAction func didClickEditButton(_ sender: Any) {
// delegate?.didClickEditButton()
isEditing = true
latTextField.layer.borderWidth = 1.0
lngTextField.layer.borderWidth = 1.0
latTextField.isEnabled = true
lngTextField.isEnabled = true
saveButton.isHidden = false
}
@IBAction func saveButtonTapped(_ sender: Any) {
if isEditing == true {
if let lat = latTextField.text {
ProductData.shared.latitude = Double(lat)
}
if let lng = lngTextField.text {
ProductData.shared.longitude = Double(lng)
}
latTextField.layer.borderWidth = 0.0
lngTextField.layer.borderWidth = 0.0
latTextField.isEnabled = false
lngTextField.isEnabled = false
self.saveButton.setTitle("Save", for: .normal)
isEditing = false
} else {
self.saveButton.setTitle("Cancel", for: .normal)
delegate?.didClickSaveButton()
}
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
if self.bounds.contains(point) {
return true
} else {
return self.subviews.contains { $0.frame.contains(point) }
}
}
}
protocol CustomCalloutViewDelegate {
func didClickEditButton()
func didClickSaveButton()
}
知道我怎么能做到这一点吗?也许以一般的方式。
先感谢您
解决方案
这是DSCenterPinMapView的链接。我推荐你使用的 CocoaPod。
它是一个自定义的 MapView,带有动画和可自定义的中心图钉,可用于在地图中选择位置。
如果您不熟悉 CocoaPods,这里也是安装指南。
您应该安装 Pod 然后,作为您问题的解决方案:
- 实现委托,以便您可以获得引脚掉落的位置。
pinMapView.delegate = self
extension MyViewController: DSCenterPinMapViewDelegate {
func didStartDragging() {
// My custom actions
}
func didEndDragging() {
// My custom actions
selectedLocation = pinMapView.mapview.centerCoordinate
// Update Text field
}
}
- 完成在 TextFields 上添加坐标后,您应该调用
pinMapView.center(on coordinate: myTextFieldCoordinate)
将地图置于所需位置的中心。
推荐阅读
- loops - 下拉列表的所有值的循环脚本
- javascript - ReferenceError:期望未在反应应用程序中定义
- java - JOGL 和 Visual Studio Code 的问题
- mysql - mysql错误!是否可以在mysql中使用表变量?
- swift - 如何确定 NSMagnificationGesture 是捏合还是缩放
- angular - 如何将 svg/png 格式的图表发送到 PDFMake
- javascript - 多图表页面上每个图表上的 D3 鼠标悬停操作
- javascript - 如何在非 React 组件中使用钩子?
- nlp - 我们可以训练 Spacy 进行文本摘要吗
- azure-data-explorer - Kusto 查询仪表板中的聚合图表 (ADX)