使用Xcode 11 beta 7的SwiftUI不会更新List / ForEach的内容

时间:2019-08-30 19:27:06

标签: swift swiftui xcode11 swiftui-list

我一直在尝试一个简单的功能,将新条目添加到列表中。视图将只添加一个新生成的。项目(无需用户输入)。

gridval = grid[i][j]

这曾经在以前的Beta中起作用,但是由于某种原因,它不再起作用了。当我单击“添加”时,应用程序会调用struct PeopleList: View { @ObservedObject var people: PersonStore var body: some View { NavigationView { VStack { Section { Button(action: add) { Text("Add") } } Section { List { ForEach(people.people) { person in NavigationLink(destination: PersonDetail(person: person)) { PersonRow(person: person) } } } } } } .navigationBarTitle(Text("People")) .listStyle(GroupedListStyle()) } func add() { let newID = (people.people.last?.id ?? 0) + 1 self.people.people.append(Person(id: newID, name: "")) } } 函数,并将新条目添加到数组中,但视图根本不会更新。

这些是支持类:

add()

以及支持视图:

    class PersonStore: ObservableObject {

    var people: [Person] {
        willSet {
            willChange.send()
        }
    }

    init(people: [Person] = []) {
        self.people = people
    }

    var willChange = PassthroughSubject<Void, Never>()
}

class Person: ObservableObject, Identifiable {

    var id: Int = 0 {
        willSet {
            willChange.send()
        }
    }

    var name: String {
        willSet {
            willChange.send()
        }
    }

     init(id: Int, name: String) {
        self.id = id
        self.name = name
    }

    var willChange = PassthroughSubject<Void, Never>()
}

#if DEBUG

let data = [
    Person(id: 1, name: "David"),
    Person(id: 2, name: "Anne"),
    Person(id: 3, name: "Carl"),
    Person(id: 4, name: "Amy"),
    Person(id: 5, name: "Daisy"),
    Person(id: 6, name: "Mike"),
]

#endif

我发现某个人的问题在这里看起来有点相关: SwiftUI: View content not reloading if @ObservedObject is a subclass of UIViewController. Is this a bug or am I missing something? 和这里: SwiftUI @Binding doesn't refresh View

1 个答案:

答案 0 :(得分:2)

问题在于,当您实现自己的ObservableObject时,使用了错误的发布者。 ObservableObject协议创建了objectWillChange发布者,但您从未使用过它,因此SwiftUI永远不会收到任何更改的通知。


class Person: ObservableObject, Identifiable {
    let id: Int

    @Published
    var name: String

    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }
}

我还没有通过编译器运行它,所以可能会有一些错别字。

您不必使用@Published,但对于像您这样的简单情况,它会更容易。当然,您还需要更新其他课程。

另外一个小的东西,ID是永不改变的,List等。用它来将数据与他们创建的视图联系起来。