在 ObservableObject 中重新加载 @Published 数组时,SwiftUI ForEach List 保留修改后的值
SwifUI ForEach List keeps modified values when reloading a @Published array inside ObservableObject
我有一个 SwiftUI 列表,它使用绑定到 ObservableObject
内的 @Published 数组的 ForEach 循环填充
列表中的元素可以用 on/off 标志修改。当列表被清除时,所有项目似乎都从 UI 中删除,但是当数据被重新获取并加载到 @Published 数组中时,UI 仍然显示先前修改的元素的状态。正如您在以下视频中看到的那样:
重现它的代码:
struct ListView: View {
@ObservedObject private var viewModel = ListViewModel()
var body: some View {
VStack {
List {
ForEach(viewModel.list, id: \.self) { element in
ElementRow(element: element)
}
}
HStack {
Button(action: { viewModel.fetch() }) { Text("Refresh") }
Button(action: { viewModel.remove() }) { Text("Remove") }
}
}.onAppear {
viewModel.fetch()
}
}
}
struct ElementRow: View {
@ObservedObject var element: ElementViewModel
var body: some View {
HStack {
Text(element.id)
Spacer()
Toggle("", isOn: $element.on )
}
}
}
class ListViewModel : ObservableObject {
@Published var list: [ElementViewModel] = []
func fetch() {
list.append(contentsOf: [ElementViewModel(id: "0", on: false), ElementViewModel(id: "1", on: false)])
}
func remove() {
list.removeAll()
}
}
class ElementViewModel : ObservableObject, Hashable {
var id: String = ""
@Published var on: Bool = false
init(id: String, on: Bool) {
self.id = id
self.on = on
}
static func == (lhs: ElementViewModel, rhs: ElementViewModel) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
需要更改什么才能使列表中的所有元素在刷新时保持关闭状态?
您的模型对象被解释为相等,因此视图不会更新(List
缓存行类似于 UITableView
)。
在下面找到修复程序。使用 Xcode 12.4 / iOS 14.4
测试
class ElementViewModel : ObservableObject, Hashable {
// ... other code
static func == (lhs: ElementViewModel, rhs: ElementViewModel) -> Bool {
lhs.id == rhs.id && lhs.on == rhs.on // << here !!
}
// ... other code
}
我有一个 SwiftUI 列表,它使用绑定到 ObservableObject
内的 @Published 数组的 ForEach 循环填充列表中的元素可以用 on/off 标志修改。当列表被清除时,所有项目似乎都从 UI 中删除,但是当数据被重新获取并加载到 @Published 数组中时,UI 仍然显示先前修改的元素的状态。正如您在以下视频中看到的那样:
重现它的代码:
struct ListView: View {
@ObservedObject private var viewModel = ListViewModel()
var body: some View {
VStack {
List {
ForEach(viewModel.list, id: \.self) { element in
ElementRow(element: element)
}
}
HStack {
Button(action: { viewModel.fetch() }) { Text("Refresh") }
Button(action: { viewModel.remove() }) { Text("Remove") }
}
}.onAppear {
viewModel.fetch()
}
}
}
struct ElementRow: View {
@ObservedObject var element: ElementViewModel
var body: some View {
HStack {
Text(element.id)
Spacer()
Toggle("", isOn: $element.on )
}
}
}
class ListViewModel : ObservableObject {
@Published var list: [ElementViewModel] = []
func fetch() {
list.append(contentsOf: [ElementViewModel(id: "0", on: false), ElementViewModel(id: "1", on: false)])
}
func remove() {
list.removeAll()
}
}
class ElementViewModel : ObservableObject, Hashable {
var id: String = ""
@Published var on: Bool = false
init(id: String, on: Bool) {
self.id = id
self.on = on
}
static func == (lhs: ElementViewModel, rhs: ElementViewModel) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
需要更改什么才能使列表中的所有元素在刷新时保持关闭状态?
您的模型对象被解释为相等,因此视图不会更新(List
缓存行类似于 UITableView
)。
在下面找到修复程序。使用 Xcode 12.4 / iOS 14.4
测试class ElementViewModel : ObservableObject, Hashable {
// ... other code
static func == (lhs: ElementViewModel, rhs: ElementViewModel) -> Bool {
lhs.id == rhs.id && lhs.on == rhs.on // << here !!
}
// ... other code
}