假设我有一个Employee类,可以观察其图片属性。
internal class Employee: CustomDebugStringConvertible, Identifiable, ObservableObject {
internal let name: String
internal let role: Role
@Published internal var picture: UIImage?
}
带有一个存储一组雇员的类。此数组可能稍后会发生突变,因此它是一个@Published属性:
internal class EmployeeStorage: ObservableObject {
@Published internal private(set) var employees: [Employee]
}
现在,我有一个使用员工存储的视图列表:
struct EmployeeList: View {
@ObservedObject var employeeStorage = EmployeeStorage.sharedInstance
var body: some View {
// Uses employeeStorage.employee property to draw itself
}
}
该列表用于内容视图:
struct ContentView: View {
@ObservedObject var employeeStorage = EmployeeStorage.sharedInstance
var body: some View {
// Uses an EmployeeList value
}
}
比方说,现在EmployeeStorage对象发生了变化,从而使雇员数组发生了变化:这有效地更新了UI,我可以看到该列表已使用新的雇员集合进行了更新。问题:当员工的图片属性更改时,如果我想获得相同的效果怎么办?我以为这足够了,但就我而言(我有一个更复杂的示例),如果员工的图像发生更改,则不会更新UI。怎么做?
答案 0 :(得分:1)
您的代码中有几个问题。
Employee
模型
ObservableObject
。UIImage
!?如果您要从Web Api异步获取数据,只需使用Image
,甚至可以使用URL。
// Employee Model
struct Employee: Codable, Identifiable {
let name: String
let role: Role
let imageUrl: String
let picture: Image
}
EmployeeStorage
EmployeeStorage
用作单例的方式存在问题。 Apple建议您最好使用@EnvironmentObject
属性传递视图及其子视图之间共享的数据。超级简单,但功能强大!话虽如此,您可以按以下方式修改代码:
// Employees Store
final class EmployeeStorage: ObservableObject {
@Published var employees: [Employee]
}
// Content View
struct ContentView: View {
var employeeStorage = EmployeeStorage()
var body: some View {
...
EmployeeList()
.environmentObject(employeeStorage) // here you pass the storage to the list
}
}
// Employee List
struct EmployeeList: View {
@EnvironmentObject var employeeStorage: EmployeeStorage
var body: some View {
NavigationView {
List {
ForEach(employeeStorage.employees) { employee in
NavigationLink(
destination: EmployeeDetail()
.environmentObject(employeeStorage)
) {
EmployeeRow(employee: employee)
}
}.navigationBarTitle(Text("Employees"))
}
}
}
}
有关更多信息,您可以签出this。已经完成了您将要达到的目标。