swift - 如何在 SwiftUI 中观察数组的单个元素
问题描述
假设我有一个 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 不会更新。怎么做?
解决方案
您的代码中有几个问题。
Employee
模型- 你的模型应该是一个结构。
- 它不需要符合
ObservableObject
. - 你为什么用
UIImage
!?Image
如果您从 Web Api 异步获取数据,只需使用URL,也可能使用 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"))
}
}
}
}
有关更多信息,您可以查看此内容。它已经完成了你要达到的目标。