1

当此视图及其父视图所依赖的 ObservableObject 发生更改时,不会调用 UIViewRepresentable.updateUIView。

我有一个带有“@State var locationManager: LocationManager”的 GameView,它作为绑定传递给我的 MapView。MapView 符合 UIViewRepresentable 协议。LocationManager 除其他外符合 ObservableObject 并具有以下与一致性相关的代码:

var didChange = PassthroughSubject<locationmanager, Never>()  


    var lastKnownLocation: CLLocation {  
        didSet {  

            // Propagate the update to the observers.  
            didChange.send(self)  
            print("Finished propagating lastKnownLocation to the observers.")  
        }  
}

我想每次 LocationManager.lastKnownLocation 更改时都必须更新 GameView 和 MapView 。在实践中,当我按主页按钮退出应用程序时,我只会看到 MapView.updateUIView() 被调用。此时控制进入 updateUIView() 并且当我再次打开应用程序(不是编译安装运行)时,我得到了更新。这也发生在 GameView() 出现后不久。

我对 SwiftUI 如何工作的理解是错误的还是一些错误?我怎样才能正确?

struct GameView: View { 
    @State var locationManager: LocationManager 


    var body: some View { 
        MapView(locationManager: $locationManager)
    }
}

struct MapView: UIViewRepresentable {

    @Binding var locationManager: LocationManager

   func makeUIView(context: Context) -> GMSMapView{ ... }

   func updateUIView(_ mapView: GMSMapView, context: Context) { ... }

}

class LocationManager: NSObject, CLLocationManagerDelegate, ObservableObject {

    var didChange = PassthroughSubject<LocationManager, Never>()

    var lastKnownLocation: CLLocation {
        didSet {


            // Propagate the update to the observers.
            didChange.send(self)
            print("Finished propagating lastKnownLocation to the observers.")
        }
    }

    ...

}

我希望每次更改 LocationManager.lastKnownLocation 都会调用 MapView.updateUIView() 。实际上,只有当我按主页按钮退出应用程序(并再次输入)时才会发生通话

4

1 回答 1

0

像这样改变 MapView

struct MapView: UIViewRepresentable {
  @State var locationManager = LocationManager()

  func makeUIView(context: Context) -> GMSMapView{
    let view = GMSMapView(frame: .zero)
    ...
    willAppear(context)
    return view
  }

  func updateUIView(_ mapView: GMSMapView, context: Context) { ... }

  func makeCoordinator() -> MapView.Coordinator {
    return Coordinator()
  }

  static func dismantleUIView(_ uiView: GMSMapView, coordinator: MapView.Coordinator) {
    coordinator.cancellable.removeAll()
  }

  class Coordinator {
    var cancellable = Set<AnyCancellable>()
  }
}

extension MapView {
  func willAppear(_ context: Context) {
    locationManager.didChange.sink{
      print("location: \($0)")
    }.store(in: &context.coordinator.cancellable)

    locationManager.startUpdating()
  }
}

我认为这个方法locationManager.startUpdating()locationManager.stopUpdating()需要调用另一个类。

于 2019-12-20T09:32:33.377 回答