如何在 SwiftUI 中观察数组的单个元素

Ram*_*uri 6 swift swiftui

假设我有一个 Employee 类,它的图片属性可以被观察到。

internal class Employee: CustomDebugStringConvertible, Identifiable, ObservableObject {
    internal let name: String
    internal let role: Role
    @Published internal var picture: UIImage?
}
Run Code Online (Sandbox Code Playgroud)

使用一个存储员工数组的类。这个数组可能会在以后发生变化,所以它是一个 @Published 属性:

internal class EmployeeStorage: ObservableObject {
    @Published internal private(set) var employees: [Employee]
}
Run Code Online (Sandbox Code Playgroud)

现在我有一个使用员工存储的视图列表:

struct EmployeeList: View {
    @ObservedObject var employeeStorage = EmployeeStorage.sharedInstance

    var body: some View {
        // Uses employeeStorage.employee property to draw itself
    }
}
Run Code Online (Sandbox Code Playgroud)

该列表用于内容视图:

struct ContentView: View {
    @ObservedObject var employeeStorage = EmployeeStorage.sharedInstance

    var body: some View {
        // Uses an EmployeeList value
    }
}
Run Code Online (Sandbox Code Playgroud)

假设现在 EmployeeStorage 对象的变化改变了雇员数组:这有效地更新了 UI,我可以看到列表更新了新的雇员集合。问题:如果我想在员工的图片属性发生变化时达到同样的效果怎么办?我认为这已经足够了,但在我的情况下(我有一个更复杂的例子),如果员工的图像发生变化,UI 不会更新。怎么做?

Al_*_*___ 4

您的代码中有几个问题。

  • 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
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • EmployeeStorage

    • EmployeeStorage我怀疑你作为单例使用的方式有问题。Apple 建议您最好使用@EnvironmentObject属性来传递视图及其子视图之间共享的数据。它超级简单,但很强大!

话虽如此,您可以按如下方式修改代码:

// Employee Model
struct Employee: Codable, Identifiable {
    let name: String
    let role: Role
    let imageUrl: String
    let picture: Image
}
Run Code Online (Sandbox Code Playgroud)

欲了解更多信息,您可以查看内容。你想要实现的目标已经完成了。