我有2个部分。
顶部包含未选中的项目。
底部包含选中的项目。
当我选中/取消选中该项目时,我能够在两个部分之间实现漂亮的移动动画。
使用 Diffable Data Source 实现非常简单。
enum Section: Hashable {
case unchecked
case checked
}
func applySnapshot(_ animatingDifferences: Bool) {
var snapshot = Snapshot()
snapshot.appendSections([.unchecked])
if !checkedChecklists.isEmpty {
snapshot.appendSections([.checked])
}
snapshot.appendItems(uncheckedChecklists, toSection: .unchecked)
if !checkedChecklists.isEmpty {
snapshot.appendItems(checkedChecklists, toSection: .checked)
}
dataSource.apply(snapshot, animatingDifferences: animatingDifferences)
}
func checkedButtonClicked(_ checklistCell: ChecklistCell, _ checked: Bool) {
guard let indexPath = collectionView.indexPath(for: checklistCell) else { return }
let section = indexPath.section
let item = indexPath.item
if (section == 0) {
// Unchecked
uncheckedChecklists[item].checked = checked
} else if (section == 1) {
// Checked
checkedChecklists[item].checked = checked
} else {
precondition(false)
}
applySnapshot(true)
}
但是,对于底部的标题,我不想显示“带有选中项目的标题” ,而是显示选中项目的计数。我修改代码如下。
enum Section: Hashable {
case unchecked
case checked(Int)
}
func applySnapshot(_ animatingDifferences: Bool) {
var snapshot = Snapshot()
snapshot.appendSections([.unchecked])
if !checkedChecklists.isEmpty {
snapshot.appendSections([.checked(checkedChecklists.count)])
}
snapshot.appendItems(uncheckedChecklists, toSection: .unchecked)
if !checkedChecklists.isEmpty {
snapshot.appendItems(checkedChecklists, toSection: .checked(checkedChecklists.count))
}
dataSource.apply(snapshot, animatingDifferences: animatingDifferences)
}
添加了一个附加代码以在标题中显示计数。
class ChecklistHeader: UICollectionReusableView {
...
func update(_ section: NewChecklistViewController.Section) {
switch section {
case .unchecked:
label.text = "Header with unchecked item"
case .checked(let count):
label.text = "Header with checked item \(count)"
}
}
private func makeDataSource() -> DataSource {
let dataSource = DataSource(
...
)
dataSource.supplementaryViewProvider = { collectionView, kind, indexPath in
if kind == UICollectionView.elementKindSectionHeader {
guard let checklistHeader = collectionView.dequeueReusableSupplementaryView(
ofKind: kind,
withReuseIdentifier: "header",
for: indexPath) as? ChecklistHeader else {
return nil
}
let sectionIdentifier = self.dataSource.snapshot().sectionIdentifiers[indexPath.section]
if let section = sectionIdentifier as? Section {
checklistHeader.update(section)
}
checklistHeader.delegate = self
return checklistHeader
} else if kind == UICollectionView.elementKindSectionFooter {
...
}
return nil
}
return dataSource
}
这是结果
如果你仔细观察
- 部分之间不再有移动动画。
- 这是因为,Diffable Data Source 将删除带有标识符的旧底部
.check(1)
,并用带有新标识符的新底部替换.check(2)
。
我想知道,我怎样才能保留部分之间的移动动画,但能够更新标题的内容?