2

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

3 回答 3

3

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

ps

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

于 2020-03-23T13:33:35.170 回答
0

改变

@ObservedObject var vitallist = VitalList()

@EnvironmentObject var vitallist = VitalList()
于 2020-01-28T09:24:29.770 回答
0

代码看起来不错。我向 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

于 2020-01-28T19:34:51.067 回答