我有一个问题NSDiffableDataSource
。我创建了这个基本示例,其中包含一个UICollectionView
显示随机数的单个项目:
import UIKit
class ViewController: UIViewController {
enum Section {
case main
}
enum Item {
case myItem
}
var collectionView: UICollectionView!
var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
lazy var myCellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Void> { (cell, indexPath, _) in
print("Cell registration called")
var content = cell.defaultContentConfiguration()
content.text = "\(Int.random(in: 0...10000))"
cell.contentConfiguration = content
}
override func viewDidLoad() {
super.viewDidLoad()
var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
let layout = UICollectionViewCompositionalLayout.list(using: config)
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = .systemGroupedBackground
view.addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
collectionView.topAnchor.constraint(equalTo: view.topAnchor),
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView, cellProvider: { [unowned self] (collectionView, indexPath, item) -> UICollectionViewCell? in
switch item {
case .myItem:
return collectionView.dequeueConfiguredReusableCell(using: myCellRegistration, for: indexPath, item: ())
}
})
DispatchQueue.global(qos: .background).async {
while true {
sleep(2)
DispatchQueue.main.async {
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.main])
snapshot.appendItems([.myItem])
self.dataSource.apply(snapshot, animatingDifferences: true)
}
}
}
}
}
每 2 秒,我将相同的快照重新应用到数据源。由于快照没有改变,我希望单元格也不会更新。就是这样……有点。从视觉上看,单元格没有变化(显示的数字保持不变)。但是,每次快照更新时,数据源实际上都会调用单元注册闭包,因此单元的内容配置确实会发生变化。它只是没有被绘制。
有人知道这里发生了什么吗?
提供一点背景知识:我问这个的原因是我想Combine
publisher
在创建单元格的内容配置时订阅一个。然后发布者发布单元格的数据,单元格可以更新其视图,允许自定义动画。(我可以简单地将数据放入 中item identifier
,但是任何数据更改只会导致单元格交叉淡入到新的单元格中。这不好)。
它看起来像这样:
// Event.Cell is some custom cell with a custom content configuration
lazy var myCellRegistration = UICollectionView.CellRegistration<Event.Cell, Void> { [unowned self] (cell, indexPath, _) in
var content = Event.ContentConfiguration()
self.myEventPublisher.sink { event in
content.event = event
cell.contentConfiguration = content // Re-set the contentConfiguration
}.store(in: &content.disposeBag) // store the subscriber in a dispose bag inside the content configuration
}
由于与发布者和订阅者一起工作可能很棘手(内存泄漏和其他东西),我需要知道如何在不引起任何问题的情况下做到这一点,并且快照的行为很奇怪。至少在我看来是这样的