我在以芝加哥为中心的视图中有一张地图。我希望用户能够在地图上放置图钉/注释,然后检索这些坐标。该地图可以很好地加载芝加哥,但我无法使用注释代码。
我似乎找不到SwiftUI的答案。只有Swift和Storyboard。我觉得我有99%的代码,但各部分的位置不正确。我提供了错误所在的屏幕截图。感谢您的帮助。
import SwiftUI
import MapKit
struct EntireMapView: UIViewRepresentable {
func updateUIView(_ mapView: MKMapView, context: Context) {
mapView.delegate = context.coordinator
let longPressGesture = UILongPressGestureRecognizer(target: mapView, action: #selector(EntireMapViewCoordinator.addAnnotation(gesture:)))
mapView.addGestureRecognizer(longPressGesture)
let span = MKCoordinateSpan(latitudeDelta: 0.3, longitudeDelta: 0.3)
var chicagoCoordinate = CLLocationCoordinate2D()
chicagoCoordinate.latitude = 41.878113
chicagoCoordinate.longitude = -87.629799
let region = MKCoordinateRegion(center: chicagoCoordinate, span: span)
mapView.setRegion(region, animated: true)
}
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView(frame: .zero)
mapView.delegate = context.coordinator
return mapView
}
func makeCoordinator() -> EntireMapViewCoordinator {
return EntireMapViewCoordinator(self)
}
class EntireMapViewCoordinator: NSObject, MKMapViewDelegate {
var entireMapViewController: EntireMapView
init(_ control: EntireMapView) {
self.entireMapViewController = control
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
return (annotation as? MKAnnotationView)!
}
@objc func addAnnotation(gesture: UILongPressGestureRecognizer) {
if gesture.state == .ended {
let point = gesture.location(in: self.mapView) **<--- ERROR HERE**
let coordinate = mapView.convert(point, toCoordinateFrom: mapView)
var annotation = MKPointAnnotation()
annotation.coordinate = coordinate
self.mapView.addAnnotation(annotation) **<--- ERROR HERE**
}
}
}
}
struct EntireMapView_Previews: PreviewProvider {
static var previews: some View {
EntireMapView()
}
}
答案 0 :(得分:1)
我不知道您是否还在寻找答案。但是这里是一个。我为此问题付出了很多努力,我不知道我的答案是否正确,但是它对我有用,所以这里是:
@objc func addAnnotation(gesture: UITapGestureRecognizer){
if let mapView = gestureRecognizer.view as? MKMApView{
let point = gestureRecognizer.location(in: mapView)
let coordinate = mapView.convert(point, toCoordinateFrom: mapView)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
DispatchQueue.main.async{
mapView.addAnnotation(annotation)
}
}
}
如您所见,我使用的不是UILongPressGestureRecognizer,而是UITapGestureRecognize。
免责声明:我不知道这是否是最好的方法!半年前我才刚开始进行swift / swiftUI编程:),这是我的第一个答案。
进一步的实现:您应该只收集数组中的所有注释,并从updateUIView方法中更新mapView。我在这里使用DispatchQueue.main.async时不知道我是否正确。但是每当我遇到Ui的变化时,我都认为您应该在主线程上完成
答案 1 :(得分:1)
这是答案的完整代码。这主要归功于@yeezy,因为使用以下行获取视图:let mapView = gestureRecognizer.view as? MKMApView
是该问题中的主要错误。
struct EntireMapView: UIViewRepresentable {
func updateUIView(_ mapView: MKMapView, context: Context) {
let span = MKCoordinateSpan(latitudeDelta: 0.3, longitudeDelta: 0.3)
var chicagoCoordinate = CLLocationCoordinate2D()
chicagoCoordinate.latitude = 41.878113
chicagoCoordinate.longitude = -87.629799
let region = MKCoordinateRegion(center: chicagoCoordinate, span: span)
mapView.setRegion(region, animated: true)
}
func makeUIView(context: Context) -> MKMapView {
let myMap = MKMapView(frame: .zero)
let longPress = UILongPressGestureRecognizer(target: context.coordinator, action: #selector(EntireMapViewCoordinator.addAnnotation(gesture:)))
longPress.minimumPressDuration = 1
myMap.addGestureRecognizer(longPress)
myMap.delegate = context.coordinator
return myMap
}
func makeCoordinator() -> EntireMapViewCoordinator {
return EntireMapViewCoordinator(self)
}
class EntireMapViewCoordinator: NSObject, MKMapViewDelegate {
var entireMapViewController: EntireMapView
init(_ control: EntireMapView) {
self.entireMapViewController = control
}
@objc func addAnnotation(gesture: UIGestureRecognizer) {
if gesture.state == .ended {
if let mapView = gesture.view as? MKMapView {
let point = gesture.location(in: mapView)
let coordinate = mapView.convert(point, toCoordinateFrom: mapView)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
mapView.addAnnotation(annotation)
}
}
}
}
}
答案 2 :(得分:0)
我首先将mapView.delegate = context.coordinator
从updateUIView中移除。在makeUIView(您已经在做)中,该操作只能执行一次。