如何使可观察对象更新列表?

时间:2020-01-26 13:54:25

标签: arrays swift list swiftui observableobject

所以我知道我的项目已添加到“ 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)
                    }
                }
              }
            }
          }
        }

3 个答案:

答案 0 :(得分:2)

我也有同样的问题。 我不知道为什么,但是可以在数组中创建一个新元素,而不更改元素本身。我确认直接更新仅适用于数据,而不适用于绑定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) }
...

p.s。

更改Tobuy 要构造的类使直接元素更新有效,上面的注释部分。这引用了Apple的官方教程:“处理用户输入”

答案 1 :(得分:0)

更改

@ObservedObject var vitallist = VitalList()

@EnvironmentObject var vitallist = VitalList()

答案 2 :(得分:0)

代码似乎很好。我在VitalList中添加了一个简单的添加方法

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