Передача координат карты на карту UIKit и Pin-код карты

#swiftui #ios14

Вопрос:

У меня есть приложение, которое отображает записи о расходах в списке. При нажатии на любую запись отобразится дополнительная информация и карта местоположения транзакции. Каждая запись содержит координаты карты для этой конкретной записи.

Я хотел бы использовать карту UIKit с параметрами стандартного, гибридного или спутникового просмотра. Ниже приведен пример кода карты, который будет отображать три типа карт, но мне нужна помощь в передаче координат и обработке pin-кода карты.

Дайте мне знать, если вам понадобится увидеть какой-либо дополнительный код или у вас возникнут вопросы о моем коде. Спасибо

 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 с картой и pin-кодом карты, показывающий, как координаты передаются на карты. 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
       }
   }
}
 

Ответ №1:

Я не показываю здесь все детали. Выбор сегментированного типа карты показан немного ниже карты, поэтому я не использую ZStack.

Параметр состояния типа карты хранится на уровне выше, потому что у меня есть несколько разные версии для портретного и ландшафтного режимов.

@State private var Тип карты: MKMapType = .стандартный

 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())
        }
    }
}