如何将更改发布到对象数组中的单个对象

时间:2020-03-16 23:10:18

标签: swiftui

我有以下课程

class ListItem: Identifiable {
    var id: UUID
    var name: String
    var description: String
    var isFavorite: Bool

    var debugDescription: String {
        return "Name: \(self.name) | Favorite?: \(self.isFavorite)"
    }

    public init(name: String) {
        self.name = name
        id = UUID()
        self.description = "Some text describing why \(self.name.lowercased()) is awesome"
        self.isFavorite = false
    }
}


class ListItems: ObservableObject {
    @Published var items: [ListItem]

    let defaultAnimals = ["Ant", "Bear", "Cat", "Dog", "Elephant", 
          "Fish", "Giraffe", "Hyena", "Iguana", "Jackal", "Kingfisher", "Leopard", "Monkey"]

    public init(animals: [String] = []) {
        let animalList: [String] = animals.count > 0 ? animals : defaultAnimals
        self.items = animalList.sorted {
            $0.lowercased() < $1.lowercased()
        }.map {
            ListItem(name: $0.firstUppercased)
        }
    }
}

ContentView

中的以下图像视图
struct ContentView: View {
    @ObservedObject var list: ListItems = ListItems()
    var body: some View {
        List(list.items) {
            animal in HStack {
                // ...
                Image(systemName: animal.isFavorite ? "heart.fill" : "heart").foregroundColor(.pink).onTapGesture {
                    let index = self.list.items.firstIndex { $0.id == animal.id } ?? -1
                    if (index >= 0) {
                        self.list.items[index].isFavorite = !animal.isFavorite
                        self.list.items = Array(self.list.items[0...self.list.items.count-1]) // <--
                    }
                }
                // ...
            }
        }
    }
}

每次点击图像视图时,我基本上都是这样重新分配整个数组,以便更改可以反映在UI中

self.list.items = Array(self.list.items[0...self.list.items.count-1])

我的问题:如何重构代码以防止每次对象属性发生更改时都重新分配整个对象数组?

我对Swift和iOS开发是相当陌生的,不确定是否缺少基本知识。

1 个答案:

答案 0 :(得分:1)

将ListItem声明为 struct 而不是类,这样在isFavorite更改时将通知视图。还有一点建议;您可以使用toggle更改布尔值:self.list.items[index].isFavorite.toggle()