【发布时间】:2019-11-29 16:19:28
【问题描述】:
UIViewControllerRepresentable 从 ViewController 接收图像。此图像应可用于 SwiftUI 视图。
ObservableObject:
class CurrentImage: ObservableObject {
var didChange = PassthroughSubject<Void, Never>()
@Published var photoTaken: UIImage? = nil {didSet{didChange.send()}}
}
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>) {
}
}
ObservableObject 是“不可访问的”,因此我无法从协调器中设置图像。我在这里忽略了一些简单的事情吗?
更新 2:将值传递给 ObservableObject 仍然无法正常工作
我一直在努力解决这个问题,并尝试了十几种方法组合。但为了简化问题,我们有一个 Coordinator,其 var 代表一个 ObservableObject。在这种情况下,我将保持简单并尝试设置字符串的值。
协调员:
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"
}
}
}
}...
ObservableObject:
class CurrentPhoto: ObservableObject {
@Published var testString = "Testing string"
}
为了测试这一点,我还尝试了以下方法:
class CurrentPhoto: ObservableObject {
let objectWillChange = ObservableObjectPublisher()
var testString = "Testing String" {
willSet {
print("set string")
objectWillChange.send()
}
}
}
在第二个示例中,将调用 willSet 方法。 (它打印“设置字符串”)但是值仍然是“测试字符串”。
正在从控制器调用 ObservableObject,但值未设置或更改。
因此视图没有收到新值:
struct ContentView: View {
@ObservedObject var cameraState = CurrentPhoto()
var body: some View {
VStack{
Text("test this \(cameraState.testString)")
...
注意:将值从 VIEW 传递给 ObservableObject 是可行的,因此问题与协调器如何将值传递给 ObservedObject 的方式有关。
以下工作并将值从 View 传递给 OO:
Button(action : {
self.cameraState.testString = "from view"
}, label : {
Text("Change string")
}
【问题讨论】:
-
videoStatus未在您的 sn-p 中声明。这是什么? -
是的,抱歉,videoStatus 已更改为 currentImage。它旨在反映 ObservableObject。我确实想出了一个解决方案,我很快就会发布。