How to get at a value in a coordinator class of a UIRepresentable?

夙愿已清 提交于 2021-01-28 12:51:10

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!