Swift - 如何在具有多个部分的 collectionView 上执行 BatchUpdates
Posted
技术标签:
【中文标题】Swift - 如何在具有多个部分的 collectionView 上执行 BatchUpdates【英文标题】:Swift -How to performBatchUpdates on a collectionView with multiple sections 【发布时间】:2019-07-12 12:55:52 【问题描述】:我有一个 collectionView,它有 3 个部分,每个部分都有一个不同的单元格(将单元格的数据分成单独的部分比只有 1 个部分更容易)。
collectionView 的数据源中只有 1 个 dataModel,它会更新,但 我只需要在第一部分显示该更新(添加了一个新标签)。当我尝试运行collectionView.performBatchUpdates
时,整个布局变得一团糟,它从显示所有 3 个部分变为仅显示最后一个部分,前 2 个部分完全消失。这不是限制,因为当我弹出并推回布局时,新标签显示第一部分中的更新数据和其他 2 看起来很好的新标签是完美的。问题似乎发生在我运行执行批处理更新时
我试过了:
let updatedDataModel = ...
guard let indexOfItem = tableData.firstIndex(where: $0.itemId == updatedDataModel.itemId ) else return
tableData[indexOfItem] = updatedDataModel
let indexPath = IndexPath(item: indexOfItem, section: 0)
UIView.animate(withDuration: 0)
self.collectionView.performBatchUpdates( [weak self] in
self?.collectionView.reloadItems(at: [indexPath])
self?.collectionView.layoutIfNeeded()
) (_) in
print("success")
我试过了:
collectionView.performBatchUpdates(
let indexSet = IndexSet(integer: 0)
self.collectionView.reloadSections(indexSet)
, completion: nil)
我试过了:
let updatedDataModel = ...
guard let indexOfItem = tableData.firstIndex(where: $0.itemId == updatedDataModel.itemId ) else return
tableData[indexOfItem] = updatedDataModel
let indexPath0 = IndexPath(item: indexOfItem, section: 0)
let indexPath1 = IndexPath(item: indexOfItem, section: 1)
let indexPath2 = IndexPath(item: indexOfItem, section: 2)
UIView.animate(withDuration: 0)
self.collectionView.performBatchUpdates( [weak self] in
self?.collectionView.reloadItems(at: [indexPath0, indexPath1, indexPath2])
self?.collectionView.layoutIfNeeded()
) (_) in
print("success")
cellForItem:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
// *** this section is where the updated data (an additional label) needs to appear
if indexPath.section == 0
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: topCell, for: indexPath) as! TopCell
cell.dataModel = tableData[indexPath.item]
return cell
if indexPath.section == 1
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: middleCell, for: indexPath) as! MiddleCell
cell.dataModel = tableData[indexPath.item]
return cell
if indexPath.section == 2
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: bottomCell, for: indexPath) as! BottomCell
cell.dataModel = tableData[indexPath.item]
return cell
// if for some reason something goes wrong above but this NEVER runs
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: errorCell, for: indexPath) as! ErrorCell
return errorCell
数据源:
func numberOfSections(in collectionView: UICollectionView) -> Int
return 3
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
if section == 0
return 1
if section == 1
return tableData.count
if section == 2
return 1
return 0
我哪里出错了?
【问题讨论】:
【参考方案1】:不要使用collectionView.performBatchUpdates
,而只需编写以下内容以仅在您想要的部分中重新加载数据:
let indexSet = IndexSet(integer: 0) // Change integer to whatever section you want to reload
collectionView.reloadSections(indexSet)
如果你不想要这个UICollectionView
reload 的任何动画,请使用:
UIView.performWithoutAnimation
// same code as above
祝你好运。
【讨论】:
我会发布 numberOfSections 和 numberOfItems,item 的大小对于每个部分都有很多事情要做,它不可读。 我在问题的底部添加了它 我认为您可能刚刚帮助我找出了导致问题的原因。给我几分钟,我现在正在尝试。 @LanceSamaria 一切似乎都很好,您是否尝试过记录(打印到控制台)一些随机值并查看是否在cellForItemAt
方法中重新加载了部分?
@LanceSamaria 部分的项目大小也可能存在一些问题,但正如您所说,您不想发布它,因为代码很乱,请检查它是否正常。以上是关于Swift - 如何在具有多个部分的 collectionView 上执行 BatchUpdates的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Swift 在 Firebase 中创建具有多个属性的用户?
SWIFT:在具有多个部分的表视图中显示字典时,无法将具有标识符单元格错误的单元格出列
使用 Realm 和 Swift 的具有多个部分的 UITableView
UITableView 使用 Realm 和 Swift 具有多个按字母顺序排列的部分,多个标签与相同的数据连接