swift - SwiftUI 中数据项更改时更新列表
问题描述
ObservableObject
我有一个采用协议的活动类,并有一个items
数组属性,用于存储也采用的 Activity 对象ObservableObject
。
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 = []
}
}
我正在使用 aList
像这样动态显示我的数组
List {
ForEach(activities.items) { activity in
NavigationLink(destination: ActivityView(activity: activity)) {
HStack {
Text("\(activity.numberOfTimesCompleted)")
VStack(alignment: .leading) {
Text(activity.title)
Text(activity.description)
}
}
}
}
}
当我将 Activity 传递给不同的视图(在 NavigationLink 中)并编辑numberOfTimesCompleted
属性时,当我导航回列表时不会反映更改。如果我将一个新的 Activity 实例添加到列表中,列表会更新,并且新numberOfTimesCompleted
值会反映在我之前编辑的 Activity 中。我感觉我很接近,但我只是在学习 Swift 和 ObservableObject,因此缺少一些东西。
解决方案
这里的问题是列表视图有一个活动数组:var items: [Activity]
并且孩子有一个Activity
来自该数组的活动。您已经创建了活动Identifiable
并且该 id 是恒定的,所以发生的情况是您从数组中传入活动并修改它,但就数组而言,没有任何改变:数组中的所有对象都具有相同的ID,所以它不会重新加载任何东西。您需要触发活动的重新加载。您可能需要考虑使用环境对象或传递一个更改闭包,该更改闭包实际上在数组上执行突变,以便重建列表视图。只有当它可以检测到发布的数组与上一个值不同时,它才会重建自己。
推荐阅读
- python - 获取每行的numpy数组中最大值的索引?
- c# - 如何使用 C# 调用带有记录表输出参数的 PL/SQL 存储过程?
- php - Android 通过 PHP 连接 MySQL,但内容未通过
- r - 使用循环来用鼠标估算数据帧,使用列表中的预测矩阵
- ios - 对齐所有设备上的导航按钮
- vue.js - 即使数据不敏感,通过身份验证保护 API 是否是好的做法或有必要?
- google-chrome - 使用webpack时后台和popup如何连接
- c-preprocessor - C 预处理器宏链
- python - 无法在 Visual Studio 上运行 python 代码,启动调试编辑器后崩溃
- javascript - 在 json 对象中使用单引号的原因