【问题标题】:How do I make the Observable Object update the list?如何让 Observable Object 更新列表?
【发布时间】:2020-05-12 02:40:52
【问题描述】:

所以我知道我的项目正在添加到“vitallist”(通过在终端中打印列表),但我没有看到它们出现在列表视图中。我认为这与“ObservedObject”没有正确链接有关。有什么建议?

struct Vital: Identifiable {
    let id = UUID()
    var name: String

}

class VitalList:ObservableObject {
   @Published var vitallist = [Vital]()
}

struct Row: View {
    var vital: Vital

    @State var completed:Bool = false
    var body: some View {
        HStack{
            Image(systemName: completed ? "checkmark.circle.fill" : "circle").onTapGesture {
                self.completed.toggle()
            }
            Text(vital.name)
        }
    }
}
struct Lists: View {

    @ObservedObject var vitallist = VitalList()

    var body: some View {
        NavigationView{
            List{
                Section(header: Text("Vital")){
                    ForEach(vitallist.vitallist){ item in
                        Row(vital: item)
                    }
                }
              }
            }
          }
        }

【问题讨论】:

  • 您的代码看起来不错。你能分享一下你展示Lists视图的sn-p吗?
  • 这个@ObservedObject var vitallist = VitalList()...它是刚刚创建的,所以是空的。您在哪里填写或将填写它?

标签: arrays swift list swiftui observableobject


【解决方案1】:

我也有同样的问题。 我不知道为什么,但它可以在数组中创建一个新元素,而不是更改元素本身。我确认直接更新仅适用于数据,但不适用于绑定 UI。

在我的代码中,TobuyData 类中的元素发生了变化。


class Tobuy: Identifiable {
    let id = UUID()
    var thing: String
    var isDone = false

    init(_ thing: String, isDone: Bool = false) {
        self.thing = thing
        self.isDone = isDone
    }
}

class TobuyData: ObservableObject {
    @Published var tobuys: [Tobuy]

    init() {
        self.tobuys = [
            Tobuy("banana"),
            Tobuy("bread"),
            Tobuy("pencil"),
        ]
    }

    func toggleDone(_ tobuy: Tobuy) {
        if let j = self.tobuys.firstIndex(where: { $0.id == tobuy.id }) {
            self.tobuys[j] = Tobuy(self.tobuys[j].thing, isDone: !self.tobuys[j].isDone)
//          self.tobuys[j].isDone.toggle() // this works only in data, but not for binding UI
        }

    }
}

在视图中

struct ContentView: View {
    @EnvironmentObject var tobuyData: TobuyData

    var body: some View {

            List {
                ForEach(tobuyData.tobuys) { tobuy in

                        Text(tobuy.thing)
                            .strikethrough(tobuy.isDone)
                            .onTapGesture { self.tobuyData.toggleDone(tobuy) }
...

附言

Tobuy Class 更改为 Struct 使得直接元素更新工作,上面的注释部分。这参考了Apple的官方教程:“处理用户输入”

【讨论】:

    【解决方案2】:

    代码看起来不错。我在 VitalList 中添加了一个简单的 add 方法

    class VitalList:ObservableObject {
         @Published var vitallist = [Vital]()
    
         func addVital(){
             self.vitallist.append(Vital(name: UUID().description))
         }
    }
    

    还有一个按钮到正文

    var body: some View {
        NavigationView{
            VStack{
                Button(action: {self.vitallist.addVital()}, label: {Text("add-vital")})
                List{
                    Section(header: Text("Vital")){
                        ForEach(vitallist.vitallist){ item in
                            Row(vital: item)
                        }
                    }
                }
            }
        }
    }
    

    列表按预期更新。检查将您的项目添加到的代码

     @Published var vitallist = [Vital]()
    

    您是否使用相同的 VitalList 实例?单身人士可能会有所帮助。 https://developer.apple.com/documentation/swift/cocoa_design_patterns/managing_a_shared_resource_using_a_singleton

    【讨论】:

      【解决方案3】:

      改变

      @ObservedObject var vitallist = VitalList()
      

      @EnvironmentObject var vitallist = VitalList()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-12
        • 1970-01-01
        相关资源
        最近更新 更多