【问题标题】:SwifUI ForEach List keeps modified values when reloading a @Published array inside ObservableObjectSwiftUI ForEach List 在 ObservableObject 中重新加载 @Published 数组时保留修改后的值
【发布时间】:2021-05-21 08:12:37
【问题描述】:

我使用绑定到 ObservableObject 内的 @Published 数组的 ForEach 循环填充了一个 SwiftUI 列表

列表中的元素可以使用开/关标志进行修改。当列表被清除时,所有项目似乎都从 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)
    }
}

需要进行哪些更改才能使列表中的所有元素在刷新时保持关闭?

【问题讨论】:

    标签: ios swift listview swiftui refresh


    【解决方案1】:

    您的模型对象被解释为相等,因此不会更新视图(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
    }
    

    【讨论】:

    • 还需要更改哈希函数以使其与 == 匹配:func hash(into hasher: inout Hasher) { hasher.combine(id); hasher.combine(on) }
    猜你喜欢
    • 2021-01-25
    • 2021-10-14
    • 2020-10-04
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多