- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了以下演示 View Controller 以在最小示例中重现该问题。
在这里,我使用 UICollectionViewDiffableDataSource 将相同数据的快照重复应用到相同的集合 View ,并且每次重新加载所有单元格时,即使没有任何更改。
我想知道这是否是一个错误,或者我是否“持有错误”。
看起来这个其他用户也有同样的问题,尽管他们没有提供足够的信息来准确地重现错误:
iOS UICollectionViewDiffableDataSource reloads all data with no changes
编辑:我还发现了一个奇怪的行为 - 如果动画差异是 true
,单元格不会每次都重新加载。
import UIKit
enum Section {
case all
}
struct Item: Hashable {
var name: String = ""
var price: Double = 0.0
init(name: String, price: Double) {
self.name = name
self.price = price
}
}
class ViewController: UIViewController {
private let reuseIdentifier = "ItemCell"
private let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
private lazy var dataSource = self.configureDataSource()
private var items: [Item] = [
Item(name: "candle", price: 3.99),
Item(name: "cat", price: 2.99),
Item(name: "dribbble", price: 1.99),
Item(name: "ghost", price: 4.99),
Item(name: "hat", price: 2.99),
Item(name: "owl", price: 5.99),
Item(name: "pot", price: 1.99),
Item(name: "pumkin", price: 0.99),
Item(name: "rip", price: 7.99),
Item(name: "skull", price: 8.99),
Item(name: "sky", price: 0.99),
Item(name: "book", price: 2.99)
]
override func viewDidLoad() {
super.viewDidLoad()
// Configure the collection view:
self.collectionView.backgroundColor = .white
self.collectionView.translatesAutoresizingMaskIntoConstraints = false
self.collectionView.register(ItemCollectionViewCell.self, forCellWithReuseIdentifier: self.reuseIdentifier)
self.collectionView.dataSource = self.dataSource
self.view.addSubview(self.collectionView)
NSLayoutConstraint.activate([
self.collectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
self.collectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
self.collectionView.topAnchor.constraint(equalTo: self.view.topAnchor),
self.collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
])
// Configure the layout:
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalWidth(1/3))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
let layout = UICollectionViewCompositionalLayout(section: section)
self.collectionView.setCollectionViewLayout(layout, animated: false)
// Update the snapshot:
self.updateSnapshot()
// Update the snapshot once a second:
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
self?.updateSnapshot()
}
}
func configureDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: self.collectionView) { (collectionView, indexPath, item) -> UICollectionViewCell? in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.reuseIdentifier, for: indexPath) as! ItemCollectionViewCell
cell.configure(for: item)
return cell
}
return dataSource
}
func updateSnapshot(animatingChange: Bool = false) {
// Create a snapshot and populate the data
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.all])
snapshot.appendItems(self.items, toSection: .all)
self.dataSource.apply(snapshot, animatingDifferences: false)
}
}
class ItemCollectionViewCell: UICollectionViewCell {
private let nameLabel = UILabel()
private let priceLabel = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(self.nameLabel)
self.addSubview(self.priceLabel)
self.translatesAutoresizingMaskIntoConstraints = false
self.nameLabel.translatesAutoresizingMaskIntoConstraints = false
self.nameLabel.textAlignment = .center
self.priceLabel.translatesAutoresizingMaskIntoConstraints = false
self.priceLabel.textAlignment = .center
NSLayoutConstraint.activate([
self.nameLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor),
self.nameLabel.topAnchor.constraint(equalTo: self.topAnchor),
self.nameLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor),
self.priceLabel.topAnchor.constraint(equalTo: self.nameLabel.bottomAnchor),
self.priceLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor),
self.priceLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor),
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(for item: Item) {
print("Configuring cell for item \(item)")
self.nameLabel.text = item.name
self.priceLabel.text = "$\(item.price)"
}
}
最佳答案
我想你已经 Handlebars 指放在上面了。当你说 animatingDifferences
是false
,您要求 diffable 数据源表现得好像它不是一个 diffable 数据源。你是在说:“跳过所有那些不同的东西,只接受这些新数据。”换句话说,你说的相当于 reloadData()
.没有创建新的单元格(通过记录很容易证明这一点),因为所有单元格都已经可见;但出于同样的原因,所有可见单元格都被重新配置,这正是人们所期望的 reloadData()
.
当animatingDifferences
是 true
,另一方面,diffable 数据源会认真考虑发生了什么变化,以便在必要时可以对其进行动画处理。因此,作为所有幕后工作的结果,它知道何时可以避免在不需要时重新加载单元格(因为它可以移动单元格)。
确实,当animatingDifferences
是 true
,您可以应用反转单元格的快照,但 configure
不再被调用,因为移动单元格是所有需要做的事情:
func updateSnapshot(animatingChange: Bool = true) {
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.all])
self.items = self.items.reversed()
snapshot.appendItems(self.items, toSection: .all)
self.dataSource.apply(snapshot, animatingDifferences: animatingChange)
}
有趣的是,我也尝试了上述
shuffled
而不是
reversed
,我发现有时会重新配置一些单元格。显然,diffable 数据源的主要意图不是不重新加载单元格;这只是一种副作用。
关于ios - 为什么 UICollectionViewDiffableDataSource 在没有任何变化的情况下重新加载每个单元格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67845779/
我是 Java 新手,这是我的代码, if( a.name == b.name && a.displayname == b.displayname && a.linknam
在下面的场景中,我有一个 bool 值。根据结果,我调用完全相同的函数,唯一的区别是参数的数量。 var myBoolean = ... if (myBoolean) { retrieve
我是一名研究 C++ 的 C 开发人员: 我是否正确理解如果我抛出异常然后堆栈将展开直到找到第一个异常处理程序?是否可以在不展开的情况下在任何 throw 上打开调试器(即不离开声明它的范围或任何更高
在修复庞大代码库中的错误时,我观察到一个奇怪的情况,其中引用的动态类型从原始 Derived 类型更改为 Base 类型!我提供了最少的代码来解释问题: struct Base { // some
我正在尝试用 C# 扩展给定的代码,但由于缺乏编程经验,我有点陷入困境。 使用 Visual Studio 社区,我尝试通过控制台读出 CPU 核心温度。该代码使用开关/外壳来查找传感器的特定名称(即
这可能是一个哲学问题。 假设您正在向页面发出 AJAX 请求(这是使用 Prototype): new Ajax.Request('target.asp', { method:"post", pa
我有以下 HTML 代码,我无法在所有浏览器中正常工作: 我试图在移动到
我对 Swift 很陌生。我如何从 addPin 函数中检索注释并能够在我的 addLocation 操作 (buttonPressed) 中使用它。我正在尝试使用压力触摸在 map 上添加图钉,在两
我设置了一个详细 View ,我是否有几个 Nib 文件根据在 Root View Controller 的表中选择的项目来加载。 我发现,对于 Nibs 的类,永远不会调用 viewDidUnloa
我需要动态访问 json 文件并使用以下代码。在本例中,“bpicsel”和“temp”是变量。最终结果类似于“data[0].extit1” var title="data["+bpicsel+"]
我需要使用第三方 WCF 服务。我已经在我的证书存储中配置了所需的证书,但是在调用 WCF 服务时出现以下异常。 向 https://XXXX.com/AHSharedServices/Custome
在几个 SO 答案(1、2)中,建议如果存在冲突则不应触发 INSERT 触发器,ON CONFLICT DO NOTHING 在触发语句中。也许我理解错了,但在我的实验中似乎并非如此。 这是我的 S
如果进行修改,则会给出org.hibernate.NonUniqueObjectException。在我的 BidderBO 类(class)中 @Override @Transactional(pr
我使用 indexOf() 方法来精细地查找数组中的对象。 直到此刻我查了一些资料,发现代码应该无法正常工作。 我在reducer中尝试了上面的代码,它成功了 let tmp = state.find
假设我有以下表格: CREATE TABLE Game ( GameID INT UNSIGNED NOT NULL, GameType TINYINT UNSIGNED NOT NU
代码: Alamofire.request(URL(string: imageUrl)!).downloadProgress(closure: { (progress) in
我是一名优秀的程序员,十分优秀!