@Published 属性不会触发任何内容

时间:2021-02-18 11:38:45

标签: swift swift5

我有这个协议:

protocol MyProtocol:ObservableObject {
  var codeDetected:CodeDetected { get set }
  var codeDetectedPublished: Published<CodeDetected> { get }
  var codeDetectedPublisher: Published<CodeDetected>.Publisher { get }
}

这是代码检测

class CodeDetected:ObservableObject {
  var title: String
  var value:String

  init(title:String = "", value:String = ""){
    self.title = title
    self.value = value
  }
}

稍后上课...

class MyModel: MyProtocol {

  @Published var codeDetected:CodeDetected = CodeDetected()
  var codeDetectedPublished: Published<CodeDetected> { _codeDetected}
  var codeDetectedPublisher: Published<CodeDetected>.Publisher { $codeDetected }
}

问题是改变这个类的 codeDetected 不会触发观察它的结构体上的任何东西。

稍后实施

struct MyView: View {
  @ObservedObject let myModel = MyModel()

我正在为它设置新值

codeDetected = newCodeDetected

1 个答案:

答案 0 :(得分:3)

试着观察你的模型

@StateObject var myModel = MyModel()

如果没有 Minimal Reproducible Example,我们将在这里分崩离析。

您也没有观察到 titlevalue。在他们身上放一个 @Published,然后观察他们自己的 View

protocol MyProtocol:ObservableObject {
    var codeDetected:CodeDetected { get set }
    //var codeDetectedPublished: Published<CodeDetected> { get }
    //var codeDetectedPublisher: Published<CodeDetected>.Publisher { get }
}

class CodeDetected:ObservableObject {
    @Published var title: String
    @Published var value:String
    
    init(title:String = "init", value:String = "init"){
        self.title = title
        self.value = value
    }
}
class MyModel: MyProtocol {
    
    @Published var codeDetected:CodeDetected = CodeDetected()
    //var codeDetectedPublished: Published<CodeDetected> { _codeDetected}
    //var codeDetectedPublisher: Published<CodeDetected>.Publisher { $codeDetected }
}
struct CodeDetectedView: View {
    @StateObject var myModel = MyModel()
    var body: some View {
        VStack{
            //Can't see updates here unless you ask for them/tell the parent model there are changes
            Text(myModel.codeDetected.title)
            .onReceive(myModel.codeDetected.$title, perform: { _ in
                myModel.objectWillChange.send()
            })
            Text(myModel.codeDetected.value)
                .onReceive(myModel.codeDetected.$value, perform: { _ in
                    myModel.objectWillChange.send()
                })
            CodeDetectedSubView(codeDetected: myModel.codeDetected)
        }
    }
}
struct CodeDetectedSubView: View {
    @ObservedObject var codeDetected: CodeDetected
    var body: some View {
        //Can see here
        Text(codeDetected.title)
        Text(codeDetected.value)
        TextField("title", text: $codeDetected.title)
        TextField("value", text: $codeDetected.value)
    }
}