问题
I am using the charts package to display the elevation, when I tap the chart I get the index of the point and I want to use that index to place a marker on the map above it. I.e locations[index].coordinate.
I have the following code and I am trying to pass the index value to my mapView that is also using UIRepresentable to display the map, but I'm having a hard time figuring out how to connect to the publisher.
How do I connect the @Published in the Coordinator class to the MapKitView, so that index will be seen as an Int?
import SwiftUI
import CoreLocation
import Charts
struct ElevationGraphView: UIViewRepresentable {
typealias UIViewType = LineChartView
var locations: [CLLocation]?
let formatter = DateFormatter()
class Coordinator: NSObject, ChartViewDelegate, ObservableObject {
@Published var index: Int = 0
var parent: ElevationGraphView
init(_ parent: ElevationGraphView) {
self.parent = parent
}
func chartValueSelected(_ uiView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
if let dataSet = uiView.data?.dataSets[highlight.dataSetIndex] {
let value = dataSet.entryIndex(entry: entry)
print("Index: \(value)")
// How to get value?
}
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
struct RaceDetailView: View {
var body: some View {
VStack {
MapKitView(locations: raceDetails.locations, markers: raceDetails.pins, region: raceDetails.region)
ElevationGraphView(locations: raceDetails.locations)
struct MapKitView: UIViewRepresentable {
let locations: [CLLocation]?
let markers: [Pin]?
let region: MKCoordinateRegion?
...
let racePointMarker = RaceMarker(coordinate: locations[index].coordinate, title: "", tint: Color.black)
mapView.addAnnotation(racePointMarker)
回答1:
Most simple, as I see, would be to use external observable (to avoid tight all those things together).
Here is possible approach (so both view don't know anything about each other).
class ChartBridge: ObservableObject {
let shared = ChartBridge()
@Published var selectedIndex: Int = 0
}
and you don't need to make internal coordinator observable (that is senseless)
class Coordinator: NSObject, ChartViewDelegate {
// ... other code
func chartValueSelected(_ uiView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
if let dataSet = uiView.data?.dataSets[highlight.dataSetIndex] {
let value = dataSet.entryIndex(entry: entry)
print("Index: \(value)")
ChartBridge.shared.selectedIndex = value // << here set !!
}
}
}
and in consumer map view just observe it
struct MapKitView: UIViewRepresentable {
@ObservedObject var chart = ChartBridge.shared
// ... other code
let racePointMarker = RaceMarker(coordinate:
locations[chart.selectedIndex].coordinate, // << here consume !!
title: "", tint: Color.black)
mapView.addAnnotation(racePointMarker)
来源:https://stackoverflow.com/questions/64037381/how-to-get-at-a-value-in-a-coordinator-class-of-a-uirepresentable