在SwiftUI中使用MKMapView

jbose2ul  于 2023-06-21  发布在  Swift
关注(0)|答案(2)|浏览(157)

我在SwiftUI应用程序中有一个Map。它正在工作到一个点;但现在我希望能够轻敲它,并知道轻敲的经纬度。下面是当前代码:

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {
    @Binding var centerCoordinate: CLLocationCoordinate2D
    
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.delegate = context.coordinator
        
        let gRecognizer = UITapGestureRecognizer(target: context.coordinator,
                                action: #selector(Coordinator.tapHandler(_:)))
        mapView.addGestureRecognizer(gRecognizer)
        return mapView
    }

    func updateUIView(_ view: MKMapView, context: Context) {
        //print(#function)
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }

    class Coordinator: NSObject, MKMapViewDelegate {
        var parent: MapView

        init(_ parent: MapView) {
            self.parent = parent
        }

        let gRecognizer = UITapGestureRecognizer(target: self,
                                                 action: #selector(tapHandler(_:)))
        
        @objc func tapHandler(_ gesture: UITapGestureRecognizer) {
            print(#function)
            .... get useful information here ...
        }
    }
}

在这种状态下,我可以看到当我点击,但我没有得到我需要的信息(即坐标的点击)。我已经尝试了一些变化的代码后,搜索网。此时它尚未工作。任何相关的提示在去的路上将是非常受欢迎的。

j8ag8udp

j8ag8udp1#

我也遇到过类似的情况,这就是我所做的。我创建了Coordinator UIGestureRecognizerDelegate,并确保gRecognizer delegate被设置为它,然后将它添加到Map中。类似于:

struct MapView: UIViewRepresentable {
@Binding var centerCoordinate: CLLocationCoordinate2D

let mapView = MKMapView()

func makeUIView(context: Context) -> MKMapView {
    mapView.delegate = context.coordinator
    return mapView
}

func updateUIView(_ view: MKMapView, context: Context) {
    //print(#function)
}

func makeCoordinator() -> Coordinator {
    return Coordinator(self)
}

class Coordinator: NSObject, MKMapViewDelegate, UIGestureRecognizerDelegate {
    var parent: MapView

    var gRecognizer = UITapGestureRecognizer()

    init(_ parent: MapView) {
        self.parent = parent
        super.init()
        self.gRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapHandler)) 
        self.gRecognizer.delegate = self
        self.parent.mapView.addGestureRecognizer(gRecognizer)
    }

    @objc func tapHandler(_ gesture: UITapGestureRecognizer) {
        // position on the screen, CGPoint
        let location = gRecognizer.location(in: self.parent.mapView)
        // position on the map, CLLocationCoordinate2D
        let coordinate = self.parent.mapView.convert(location, toCoordinateFrom: self.parent.mapView)
        
    }
}
}
iszxjhcz

iszxjhcz2#

我在macOS上运行的SwiftUI应用程序在Map上获取点击位置时遇到了类似的问题,所以很明显,我必须使用NSViewRepresentable而不是UIViewRepresentable
@workingdog的回答帮了大忙;下面是我的macOS版本,它在Text视图中显示单击的位置,Z堆叠在Map的顶部:

struct MapViewRepresentable: NSViewRepresentable {
  @Binding var clickedCoordinate: CLLocationCoordinate2D
  var initialLocation: CLLocationCoordinate2D
  var initialSpan: MKCoordinateSpan

  let mapView = MKMapView()
  
  func makeNSView(context: Context) -> MKMapView {
    mapView.preferredConfiguration = MKHybridMapConfiguration(elevationStyle: .realistic)
    mapView.region = MKCoordinateRegion(center: initialLocation, span: initialSpan)
    mapView.delegate = context.coordinator
    return mapView
  }
  
  func updateNSView(_ nsView: MKMapView, context: Context) {
    
  }
  
  func makeCoordinator() -> Coordinator {
    return Coordinator(self)
  }
  
  class Coordinator: NSObject, MKMapViewDelegate, NSGestureRecognizerDelegate {
    @State var parent: MapViewRepresentable
    
    var gRecognizer = NSClickGestureRecognizer()
    
    init(_ parent: MapViewRepresentable) {
      self.parent = parent
      super.init()
      self.gRecognizer = NSClickGestureRecognizer(target: self, action: #selector(tapHandler))
      self.gRecognizer.delegate = self
      self.parent.mapView.addGestureRecognizer(gRecognizer)
    }
    
    @objc func tapHandler(_ gesture: NSClickGestureRecognizer) {
      let location = gesture.location(in: self.parent.mapView)
      let coordinate = self.parent.mapView.convert(location, toCoordinateFrom: self.parent.mapView)
      parent.clickedCoordinate = coordinate
    }
  }
}

struct MapView: View {
  private static let initialLocation = CLLocationCoordinate2D(latitude: 51.5, longitude: 0.0)  // London, UK
  private static let initialSpan = MKCoordinateSpan(latitudeDelta: 1.0, longitudeDelta: 1.0)

  @State private var clickedCoordinate: CLLocationCoordinate2D = Self.initialLocation

  var body: some View {
    ZStack {
      MapViewRepresentable(clickedCoordinate: $clickedCoordinate, initialLocation: Self.initialLocation, initialSpan: Self.initialSpan)
      HStack {
        Spacer()
        VStack(alignment: .trailing) {
          Spacer()
          Text("Clicked - Lat: \(latAsStr(clickedCoordinate.latitude)) Lon: \(lonAsStr(clickedCoordinate.longitude))")
            .background(.white).opacity(0.75)
            .foregroundColor(.black)
            .textSelection(.disabled)
            .padding(5)
        }
      }
    }
  }
  
  func latAsStr(_ lat: Double) -> String { 
    // convert lat to string
  }
  
  func lonAsStr(_ lon: Double) -> String {
    // convert lon to string
  }

}

相关问题