我有一个采用ObservableObject
协议的Activity类,并具有一个items
数组属性,该属性存储也采用ObservableObject
的Activity对象。
class Activity: ObservableObject, Codable, Identifiable {
let id = UUID()
@Published var title: String
@Published var description: String
@Published var numberOfTimesCompleted: Int = 0
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(title, forKey: .title)
try container.encode(description, forKey: .description)
try container.encode(numberOfTimesCompleted, forKey: .numberOfTimesCompleted)
}
init(title: String, description: String) {
self.title = title
self.description = description
numberOfTimesCompleted = 0
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
title = try container.decode(String.self, forKey: .title)
description = try container.decode(String.self, forKey: .description)
numberOfTimesCompleted = try container.decode(Int.self, forKey: .numberOfTimesCompleted)
}
}
class Activities: ObservableObject {
@Published var items: [Activity] {
didSet {
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(items) {
UserDefaults.standard.set(encoded, forKey: "items")
}
}
}
init() {
if let items = UserDefaults.standard.data(forKey: "items") {
let decoder = JSONDecoder()
if let decoded = try? decoder.decode([Activity].self, from: items) {
self.items = decoded
return
}
}
self.items = []
}
}
我正在使用List
这样动态显示我的数组
List {
ForEach(activities.items) { activity in
NavigationLink(destination: ActivityView(activity: activity)) {
HStack {
Text("\(activity.numberOfTimesCompleted)")
VStack(alignment: .leading) {
Text(activity.title)
Text(activity.description)
}
}
}
}
}
当我将“活动”传递到另一个视图(在NavigationLink中)并编辑numberOfTimesCompleted
属性时,当我导航回到列表时,更改不会反映出来。如果将新的Activity实例添加到列表中,列表将更新,并且新的numberOfTimesCompleted
值会反映在我之前编辑的Activity中。我有一种接近的感觉,但是我正在学习Swift和ObservableObject,因此缺少一些东西。
答案 0 :(得分:0)
这里的问题是列表视图具有一系列活动:var items: [Activity]
,而子级则具有来自该阵列的单个Activity
。您已经创建了活动Identifiable
,并且id是常量,因此发生的事情是您从数组中传递了活动并对其进行了修改,但是就数组而言,什么都没有改变:所有对象数组中的ID完全相同,因此不会重新加载任何内容。您需要触发活动的重新加载。您可能要考虑使用一个环境对象或传递一个更改闭包,该更改闭包实际上对数组执行突变,以便重建列表视图。仅当它可以检测到已发布的数组与上一个值不同时,它才会自我重建。