【问题标题】:@Published property not triggering anything@Published 属性没有触发任何东西
【发布时间】:2021-05-21 08:37:16
【问题描述】:

我有这个协议:

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

【问题讨论】:

    标签: swift swift5


    【解决方案1】:

    试着观察你的模型

    @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)
        }
    }
    

    【讨论】:

    • 不应该是@ObservedObject而不是@StateObject吗?抱歉,我在我的代码中将其命名为 @ObservedObject。未能将其添加到问题中。对不起。现已修复。
    • 当你在同一个View 中初始化时,你可以,但Apple 建议“更稳定”StateObject 为此。 ObservedObject 用于当对象来自另一个 View 时,例如使用 NavigationLink 的 CoreData 对象的 ForEach,其中对象被单独观察。
    • titlevalue 也需要包装器和观察。
    • 我为你准备了一些代码。我认为你最重要的事情是你正在链接ObservableObjects SwiftUI 不能看那么远。但是你可以通过观察项目来强制它刷新。
    猜你喜欢
    • 2015-01-03
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多