将地图坐标传递给 UIKit 地图和地图引脚

Passing Map Coordinates to a UIKit Map and Map Pin

我有一个应用程序可以在列表中显示费用条目。单击任何条目将显示其他信息和交易位置的地图。每个条目都包含该特定条目的地图坐标。

我想使用带有标准视图、混合视图或卫星视图选项的 UIKit 地图。下面是一些示例地图代码,将显示三种地图类型,但我需要帮助传递坐标和处理地图图钉。

如果您需要查看任何其他代码或对我的代码有疑问,请告诉我。谢谢

struct MapViewUIKit: UIViewRepresentable {
     
        let region: MKCoordinateRegion
        let mapType : MKMapType
        
        func makeUIView(context: Context) -> MKMapView {
            let mapView = MKMapView()
            mapView.setRegion(region, animated: false)
            mapView.mapType = mapType
            return mapView
        }
        
        func updateUIView(_ mapView: MKMapView, context: Context) {
            mapView.mapType = mapType
        }
    }
    
    
    struct ContentView: View {
     
        @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 36.15035, longitude: -115.91304) , span: MKCoordinateSpan(latitudeDelta: 0.0005, longitudeDelta: 0.0005))
      
        @State private var mapType: MKMapType = .standard
        
        var body: some View {
            ZStack {
          
                MapViewUIKit(region: region, mapType: mapType)
                    .edgesIgnoringSafeArea(.all)
                
                VStack {
                    Spacer()
                  
                    Picker("", selection: $mapType) {
                        Text("Standard").tag(MKMapType.standard)
                        Text("Satellite").tag(MKMapType.satellite)
                        Text("Hybrid").tag(MKMapType.hybrid)
                    }
                    .pickerStyle(SegmentedPickerStyle())
                    .offset(y: -40)
                    .font(.largeTitle)
                }
            }
        }
    }

下面是我当前的带有地图和地图图钉的 swiftui 代码,显示了坐标是如何传递到地图的。 ShowRow 是显示核心数据条目的逻辑的一部分。单击任何条目将显示其他数据和地图。

struct DetailView: View {
    
    var item: CurrTrans // this contains core data entries with coordinates
    var coordinate: CLLocationCoordinate2D
    var g: GeometryProxy
    
    var body: some View {
        
            VStack {
                
                ShowMap(item: item, coordinate: coordinate)
                    .frame(width: g.size.width, height: g.size.height * 0.65)
                
                ShowDetail(item: item, g: g)  // additional entry info 
                    .padding(.top, g.size.height * 0.05)
        }
    }
}

struct ShowMap: View {
    
    var coordinate: CLLocationCoordinate2D
    var item: CurrTrans

    var body: some View {
    
            HStack {
                Spacer()
                MapView(coordinate: coordinate)
                    .edgesIgnoringSafeArea(.all)
                Spacer()
  
        }
    }
}


struct Marker: Identifiable {
   let id = UUID()
   let location: MapPin // or MapMarker
}

在 MapView 中,典型的 UIKit 示例将坐标硬编码在状态参数中。我需要动态传入坐标。

struct MapView: View {
   
   var coordinate: CLLocationCoordinate2D
   
   var body: some View {
      
       Map(coordinateRegion: .constant(MKCoordinateRegion(center: coordinate,
                   span: MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005))),
                   showsUserLocation: false,
           annotationItems: [Marker(location: MapPin(coordinate: coordinate))]) { marker in
                       marker.location
       }
   }
}

我没有在这里展示所有细节。地图类型分段选择器显示在地图下方,所以我没有使用 ZStack。

地图类型状态参数存储了一个级别,因为我的纵向和横向模式版本略有不同。

@State private var mapType: MKMapType = .standard

struct ShowMap: View {
    
    var item: CurrTrans
    var coordinate: CLLocationCoordinate2D
    var g: GeometryProxy
    var mapType: MKMapType
    
    var body: some View {
        
       let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)
       let region = MKCoordinateRegion(center: coordinate, span: span)
            
       MapView(region: region, mapType: mapType, coordinate: coordinate)
            .edgesIgnoringSafeArea(.all)
        }
    }
}


struct MapView: UIViewRepresentable {
    
    let region: MKCoordinateRegion
    let mapType : MKMapType
    var coordinate: CLLocationCoordinate2D
    
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.setRegion(region, animated: true)
        
        // display a map pin
        let annotation = MKPointAnnotation()
        annotation.coordinate = coordinate
        mapView.addAnnotation(annotation)
        
        mapView.mapType = mapType
        return mapView
    }
    
    func updateUIView(_ mapView: MKMapView, context: Context) {
        mapView.mapType = mapType
    }
}


struct ShowDetail: View {
    
    var item: CurrTrans
    var g: GeometryProxy
    @Binding var mapType: MKMapType
    
    var body: some View {
            
            Picker("", selection: $mapType) { // new to end
                Text("Default").tag(MKMapType.standard)
                Text("Transit").tag(MKMapType.hybrid)
                Text("Satellite").tag(MKMapType.satellite)
            }
            .pickerStyle(SegmentedPickerStyle())
            .offset(y: -35)
            .font(.largeTitle)
        
            VStack (alignment: .leading) {
            ShowMoreDetails(item: item)
                .navigationBarTitle("Transaction Details", displayMode: .inline)
                .navigationViewStyle(StackNavigationViewStyle())
        }
    }
}