我很难找到 NSDiffableDataSourceSnapshot 的用途reloadItems(_:) https://developer.apple.com/documentation/uikit/nsdiffabledatasourcesnapshot/3375783-reloaditems:
您可能认为第二点的答案是:嗯,项目标识符对象可能还有其他一些方面,它不是其等同性的一部分,但确实反映到单元格接口中。但我发现事实并非如此。打电话后reloadItems
,表视图确实not反映变化。
因此,当我想要更改某个项目时,我最终会对快照执行以下操作:insert
在要更换的项目之后,然后是delete
原始项目的。没有快照replace
方法,这正是我所希望的reloadItems
事实证明是这样的。
(我对这些术语进行了 Stack Overflow 搜索,但发现很少——主要是几个对特定用途感到困惑的问题reloadItems
, 例如如何使用 diffable UITableView 更新表格单元格 https://stackoverflow.com/questions/60180412/how-to-update-a-table-cell-using-diffable-uitableview。所以我以更普遍的形式问,实际用途有什么anyone找到这个方法了吗?)
好吧,没有什么比拥有一个最小的可重现示例更好的了,所以这里就是一个。
使用模板 ViewController 创建一个普通的 iOS 项目,并将此代码添加到 ViewController 中。
我会一点一点地拿走它。首先,我们有一个结构体作为我们的项目标识符。 UUID 是唯一的部分,因此可等性和可散列性仅取决于它:
struct UniBool : Hashable {
let uuid : UUID
var bool : Bool
// equatability and hashability agree, only the UUID matters
func hash(into hasher: inout Hasher) {
hasher.combine(uuid)
}
static func ==(lhs:Self, rhs:Self) -> Bool {
lhs.uuid == rhs.uuid
}
}
接下来,(假)表视图和可比较数据源:
let tableView = UITableView(frame: .zero, style: .plain)
var datasource : UITableViewDiffableDataSource<String,UniBool>!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.datasource = UITableViewDiffableDataSource<String,UniBool>(tableView: self.tableView) { tv, ip, isOn in
let cell = tv.dequeueReusableCell(withIdentifier: "cell", for: ip)
return cell
}
var snap = NSDiffableDataSourceSnapshot<String,UniBool>()
snap.appendSections(["Dummy"])
snap.appendItems([UniBool(uuid: UUID(), bool: true)])
self.datasource.apply(snap, animatingDifferences: false)
}
所以我们的 diffable 数据源中只有一个 UniBool 及其bool
is true
。现在设置一个按钮来调用此操作方法,该方法尝试切换bool
使用价值reloadItems
:
@IBAction func testReload() {
if let unibool = self.datasource.itemIdentifier(for: IndexPath(row: 0, section: 0)) {
var snap = self.datasource.snapshot()
var unibool = unibool
unibool.bool = !unibool.bool
snap.reloadItems([unibool]) // this is the key line I'm trying to test!
print("this object's isOn is", unibool.bool)
print("but looking right at the snapshot, isOn is", snap.itemIdentifiers[0].bool)
delay(0.3) {
self.datasource.apply(snap, animatingDifferences: false)
}
}
}
所以事情是这样的。我说reloadItems
与 UUID 匹配的项目,但其bool
被切换:“该对象的 isON 为 false”。但当我问快照时,好吧,你有什么?它告诉我它唯一的项目标识符bool
仍然是这样.
And that这就是我要问的。如果快照不会获取新值bool
, 什么是reloadItems
首先?
显然我可以替换不同的UniBool,即具有不同 UUID 的一个。但后来我无法打电话reloadItems
;我们崩溃是因为 UniBool 尚未在数据中。我可以通过打电话解决这个问题insert
其次是remove
,这正是我解决这个问题的方法。
但我的问题是:那么什么是reloadItems
因为,如果不是因为这件事呢?