import SwiftUI
extension MultilayerDataView {
class People: ObservableObject, Identifiable {
@Published var peopleList: [Person] = []
init() {
peopleList = [
Person(name: "Alice", hobbies: [Hobbie("Reading"), Hobbie("Painting")]),
Person(name: "Bob", hobbies: [Hobbie("Swimming"), Hobbie("Cooking")])
]
}
}
class Person: ObservableObject, Identifiable {
@Published var name: String
@Published var hobbies: [Hobbie] // 数组属性
init(name: String, hobbies: [Hobbie]) {
self.name = name
self.hobbies = hobbies
}
}
class Hobbie: ObservableObject, Identifiable {
@Published var name: String
init(_ name: String) {
self.name = name
}
}
}
struct MultilayerDataView: View {
@StateObject var people: People = People()
var body: some View {
VStack {
ForEach(people.peopleList) { person in
Text(person.name)
ForEach(person.hobbies) { hobby in
Text(hobby.name)
}
Button("Add Person") {
people.peopleList.append(Person(name: "Hony", hobbies: [Hobbie("running"), Hobbie("eatting")]))
}
Button("Add Hobby") {
people.objectWillChange.send() // 重点
person.hobbies.append(MultilayerDataView.Hobbie("runing"))
}
}
}
}
}
struct MultilayerDataView_Previews: PreviewProvider {
static var previews: some View {
MultilayerDataView()
}
}
现象
上面代码,
在没有添加 people.objectWillChange.send() 这行代码前,
添加Person能够自动刷新视图,但是添加Hobby无法自动刷新
原因
多层ForEach导致的
因为hobbies是包含在people.peopleList的ForEach中,那么更新hobbies中的数据时候,虽然数据更新了,但是由于people.peopleList的数据并没有变化,所以外层ForEach代码根本不会重新执行。随意页面才不会更新。
这也是ForEach的机制,通过id标识,保证每条数据不会重复加载
解决办法
修改数据前,最外层对象调用一下这个函数objectWillChange.send(),标记需要刷新