SwiftUI无法更新类数据更新

问题描述

我遇到一种情况,您使用类数据作为数据源,并在swiftUI列表视图中显示它们,当您更新数据源时,swiftUI列表视图将不会更新,我们该怎么做?类数据是否可以通过swiftUI进行交互?

请参见代码说明:

我定义了环境对象:

import Foundation
import Combine

class DataSource: ObservableObject {
    public static let shared = DataSource()
    
    @Published var datalist: [RowData] = []
    
    func fetch() -> Void {
        for n in 1...50 {
            let data = RowData(title: "Index:\(n)",count: 0)
            datalist.insert(data,at: 0)
        }
    }
    
    func update() {
        for data in datalist {
            data.count = data.count+1
            print("\(data.title) update count to :\(data.count)")
            data.objectwillChange.send()
        }
        self.objectwillChange.send()
    }
}


在行视图中显示每个数据:

import SwiftUI

struct RowView: View {
    @State var data: RowData
    var body: some View {
        HStack{
            Text(data.title)
            Spacer()
            Text("\(data.count)")
        }.padding()
    }
}

struct RowView_Previews: PreviewProvider {
    static var previews: some View {
        RowView(data: RowData(title: "text",count: 1))
    }
}


class RowData: ObservableObject {
    var title: String = ""
    var count: Int = 0

    init(title: String,count: Int) {
        self.title = title
        self.count = count
    }
}


内容视图中,以列表视图显示数据,单击“更新”按钮时,我想刷新所有视图更新。该按钮将触发更新方法以从数据源更新类数据值。

struct ContentView: View {
    @EnvironmentObject var data: DataSource
    @State var shouldUpdate:Bool = false
    @State var localData:[RowData] = []
    
    var body: some View {
        vstack {
            Button(action: {
                // your action here
                self.data.update()
                self.shouldUpdate.toggle()
                self.localData.removeAll()
                self.localData = self.data.datalist
            }) {
                Text("update")
            }
            List {
                ForEach(0..<self.localData.count,id:\.self) { index in
                    RowView(data: self.localData[index])
                    
                }
            }
        }
        
    }
}

解决方法

好吧...我看不出拥有localData的原因,但是无论如何,这是可以正常工作的修改后的代码。

通过Xcode 12 / iOS 14测试

demo

class DataSource: ObservableObject {
    public static let shared = DataSource()

    @Published var datalist: [RowData] = []

    func fetch() -> Void {
        for n in 1...50 {
            let data = RowData(title: "Index:\(n)",count: 0)
            datalist.insert(data,at: 0)
        }
    }

    func update() {
        for data in datalist {
            data.count = data.count+1
            print("\(data.title) update count to :\(data.count)")
        }
        self.objectWillChange.send()
    }
}

struct RowView: View {
    @ObservedObject var data: RowData
    var body: some View {
        HStack{
            Text(data.title)
            Spacer()
            Text("\(data.count)")
        }.padding()
    }
}

class RowData: ObservableObject {
    @Published var title: String = ""
    @Published var count: Int = 0

    init(title: String,count: Int) {
        self.title = title
        self.count = count
    }
}

struct ContentView: View {
    @EnvironmentObject var data: DataSource
    @State var localData:[RowData] = []

    var body: some View {
        VStack {
            Button(action: {
                // your action here
                self.data.update()
                self.localData = self.data.datalist
            }) {
                Text("update")
            }
            List {
                ForEach(0..<self.localData.count,id:\.self) { index in
                    RowView(data: self.localData[index])
                }
            }
        }
        .onAppear {
            self.data.fetch()
            self.localData = self.data.datalist
        }
    }
}