【问题标题】:SwiftUI be notified when all properties of an ObservableObject are updated当 ObservableObject 的所有属性更新时通知 SwiftUI
【发布时间】:2020-05-24 22:36:33
【问题描述】:

我有一个ObservableObject


class CurrentPosition: ObservableObject {
    @Published var northEast = CLLocationCoordinate2D()
    @Published var southWest = CLLocationCoordinate2D()


    init(northEast: CLLocationCoordinate2D = CLLocationCoordinate2D(), southWest: CLLocationCoordinate2D = CLLocationCoordinate2D()) {
        self.northEast = northEast
        self.southWest = southWest
    }

    func updateCoordinates(from mapView: MKMapView) {
        self.northEast = mapView.northEastCoordinate
        self.southWest = mapView.southWestCoordinate
    }
}

我想从 MapView 更新

struct MapView: UIViewRepresentable {
    @Binding var weatherStations: [WeatherStation]
    @Binding var selectedWeatherStation: WeatherStation?

    @EnvironmentObject var currentPosition: CurrentPosition

    func makeUIView(context: Context) -> MKMapView {
        let map = MKMapView()
        map.showsUserLocation = true
        map.delegate = context.coordinator
        return map
    }

    func updateUIView(_ uiView: MKMapView, context: Context) {
        updateAnnotations(from: uiView)
    }

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


    final class Coordinator: NSObject, MKMapViewDelegate {
        var control: MapView

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

        func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
            control.currentPosition.updateCoordinates(from: mapView)
        }

    }
}

并将其传递给AppState 对象

 MapView(weatherStations: $appState.appData.weatherStations,
                        selectedWeatherStation: $selectedWeatherStation).environmentObject(self.currentPosition)
                    .edgesIgnoringSafeArea(.vertical).onReceive(currentPosition.objectWillChange) { () in
                        self.appState.currentPosition = self.currentPosition
                }}

然后将其传递给我的 API 客户端

class AppState: ObservableObject {
    @Published var appData = AppData(weatherStations: [WeatherStation]())
    var currentPosition: CurrentPosition! {
        didSet {
            api.currentPosition = self.currentPosition
        }
    }
}

我的问题是,每次我的CurrentPosition 属性之一更新时它都会通过,这意味着它首先在northEast 更新时通过,而不是在southWest 更新时通过。

当两个都完成更新后,我怎样才能只传递一个?

【问题讨论】:

    标签: swift mvvm swiftui xcode11 combine


    【解决方案1】:

    简单的方法是使用辅助struct 将其折叠成一个属性,如下所示:

    struct MapCoordinateSpan {
      let northEast: CLLocationCoordinate2D
      let southWest: CLLocationCoordinate2D
    }
    

    并修改你的CurrentPosition 看起来像这样:

    class CurrentPosition: ObservableObject {
        @Published var span: MapCoordinateSpan
    
        init(northEast: CLLocationCoordinate2D = CLLocationCoordinate2D(), southWest: CLLocationCoordinate2D = CLLocationCoordinate2D()) {
            self.span = MapCoordinateSpan(northEast: northEast, southWest: southWest)
        }
    
        func updateCoordinates(from mapView: MKMapView) {
            self.span = MapCoordinateSpan(northEast: mapView.northEastCoordinate, southWest: mapView.southWestCoordinate)
        }
    }
    

    然后绑定到span 属性,并从那里提取坐标。

    【讨论】:

      猜你喜欢
      • 2021-02-27
      • 2020-10-25
      • 2021-12-11
      • 2020-12-05
      • 2020-07-06
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      相关资源
      最近更新 更多