简体   繁体   English

SwiftUI - 来自协调器的 ObservableObject 更新

[英]SwiftUI - ObservableObject Update from Coordinator

A UIViewControllerRepresentable receives an image from a ViewController. UIViewControllerRepresentable 从 ViewController 接收图像。 This image should be made available to the SwiftUI view.此图像应可用于 SwiftUI 视图。

The ObservableObject:可观察对象:

class CurrentImage: ObservableObject  {
 var didChange = PassthroughSubject<Void, Never>()
 @Published var photoTaken: UIImage? = nil {didSet{didChange.send()}}
}

UIViewControllerRepresentable: UIViewControllerRepresentable:

struct CameraPreviewView: UIViewControllerRepresentable  {

 var currentImage: CurrentImage

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

 class Coordinator: NSObject {
  let parent: CameraPreviewView

  init(_ cameraPreviewController: CameraPreviewView) {
   self.parent = cameraPreviewController
   super.init()

   // Notification receives a copy of the image taken from the ViewController:         
   NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "imageDidChange"), object: nil, queue: OperationQueue.main){(notification) in
    if let image = notification.userInfo?["image"] as? UIImage {

      // *****ERROR: self.parent.videoStatus.photoTaken is not accessible
      self.parent.currentImage.photoTaken = image
    }
   }
  }
 }


    func makeUIViewController(context: UIViewControllerRepresentableContext<CameraPreviewView>) -> CameraViewController {
        let cameraViewController = CameraViewController()
        return cameraViewController
    }

    // View is not updating so we don't need this
    func updateUIViewController(_ cameraViewController: CameraViewController, context: UIViewControllerRepresentableContext<CameraPreviewView>) {
    }
}

The ObservableObject is 'not accessible' and so I can't set the image within it from the Coordinator. ObservableObject 是“不可访问的”,因此我无法从协调器设置其中的图像。 Am I overlooking something simple here?我在这里忽略了一些简单的事情吗?

UPDATE 2: Passing value to an ObservableObject still not working更新 2:将值传递给 ObservableObject 仍然不起作用

I've struggled with this and tried a dozen combinations of approaches.我一直在努力解决这个问题,并尝试了十几种方法组合。 But to simplify the issue, we have a Coordinator with a var representing an ObservableObject.但是为了简化问题,我们有一个 Coordinator,它带有一个表示 ObservableObject 的 var。 In this case, I'm going to keep it simple and try to set the value of a string.在这种情况下,我将保持简单并尝试设置字符串的值。

The Coordinator:协调员:

struct CameraPreviewView: UIViewControllerRepresentable  {

 var cameraPhoto = CurrentPhoto()

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

 class Coordinator: NSObject {
  let parent: CameraPreviewView
  init(_ cameraPreviewController: CameraPreviewView) {
   self.parent = cameraPreviewController
   super.init()

   NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "imageDidChange"), object: nil, queue: OperationQueue.main){(notification) in
    print("notice received")
    self.parent.cameraPhoto.testString = "This changed"
   }
  }
 }
}...

The ObservableObject:可观察对象:

 class CurrentPhoto: ObservableObject  {
  @Published var testString = "Testing string"
 }

In order to test this, I also tried the following:为了测试这一点,我还尝试了以下内容:

class CurrentPhoto: ObservableObject  {

 let objectWillChange = ObservableObjectPublisher()

 var testString = "Testing String" {
  willSet {
   print("set string")
   objectWillChange.send()
  }
 }
}

In the second example, the willSet method DOES get called.在第二个示例中,会调用 willSet 方法。 (It prints "set string") however the value remains "Testing String". (它打印“设置字符串”)但是值仍然是“测试字符串”。

The ObservableObject IS being called from the Controller but the value does not set or change. ObservableObject 正在从控制器调用,但值没有设置或更改。

Therefore the view doesn't receive a new value:因此视图不会收到新值:

struct ContentView: View {
 @ObservedObject var cameraState = CurrentPhoto()
 var body: some View {
  VStack{
   Text("test this \(cameraState.testString)")
   ...   

NOTE: passing a value from the VIEW to the ObservableObject works, so the issue is somehow connected to how the Coordinator passes value to an ObservedObject.注意:将值从 VIEW 传递给 ObservableObject 是可行的,因此问题以某种方式与协调器如何将值传递给 ObservedObject 相关。

The following works and passes a value from the View to the OO:以下工作并将值从视图传递到 OO:

Button(action : {
 self.cameraState.testString = "from view"
}, label : {
 Text("Change string")
}

This doesn't entirely solve the problem of how to bind a Coordinator to an ObservableObject.这并不能完全解决如何将 Coordinator 绑定到 ObservableObject 的问题。 However, this did achieve the intended goal, which was to return the image from the Coordinator to SwiftUI.但是,这确实实现了预期目标,即将图像从 Coordinator 返回到 SwiftUI。

The view:风景:

struct ContentView: View {

 @State private var photoInView: Image?
 @State var isRecording = true

 var body: some View {
  VStack{
   photoInView?
   .resizable()
   .scaledToFit() 
   ZStack (alignment: .bottom) {
   // Start up the CameraPreview and this will 2-way bind.  
   CameraPreviewView(isRecording: $isRecording, photoReceivedFromCoordinator: $photoInView)
   ....

And then in the UIViewRepresentable:然后在 UIViewRepresentable 中:

struct CameraPreviewView: UIViewControllerRepresentable  {

  @Binding var isRecording: Bool
  @Binding var photoReceivedFromCoordinator: Image?

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

  class Coordinator: NSObject {
   // Setting the coordinator to parent allows the coordinator to use the    @Binding
   let parent: CameraPreviewView
   init(_ cameraPreviewController: CameraPreviewView) {
    self.parent = cameraPreviewController
    super.init()

    NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "imageDidChange"), object: nil, queue: OperationQueue.main){(notification) in
    if let uiImage = notification.userInfo?["image"] as? UIImage {
     // We need an Image not a UI Image, so first we convert it
     let image = Image(uiImage: uiImage)
     // Assign the value to the parent's binding value
     self.parent.photoReceivedFromCoordinator = image
    }
   }
  }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SwiftUI - 从 NSObject 继承的 ObservableObject 在 iOS 13 中没有更新 - SwiftUI - ObservableObject that inherits from NSObject does not update in iOS 13 SwiftUI - ObservableObject 不会导致更新 - SwiftUI - ObservableObject doesn't cause update SwiftUI MacOS 使用 ObservableObject 更新状态 - SwiftUI MacOS using ObservableObject to update State 无法从 @Published ObservableObject 或 @EnvironmentObject 变量获取 SwiftUI 视图对象更新 - Can't get SwiftUI View objects to update from @Published ObservableObject or @EnvironmentObject variables iOS SwiftUI:从父级到子级的 ObservableObject - iOS SwiftUI: ObservableObject from parent to child 当 ObservableObject 属性更改时,SwiftUI UI 不会更新 - SwiftUI UI won't Update when ObservableObject Property Changes @Published in an ObservableObject vs @State on a View 导致 SwiftUI 中不可预测的更新行为 - @Published in an ObservableObject vs @State on a View leads to unpredictable update behavior in SwiftUI SwiftUI:在打开视图时条件/ ObservableObject 更改时更新视图 - SwiftUI: Update views when conditions / ObservableObject changed while view is opened SwiftUI - @Published 属性未从协调器更新视图 - SwiftUI - @Published property is not updating view from coordinator 如何从计算属性更新 ObservableObject 属性? - How to update an ObservableObject property from a computed property?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM