问题描述
节可能包含1个页眉,许多内容项和1个页脚。
对于DiffableDataSource
,大多数在线示例都使用enum
来表示Section。例如
func applySnapshot(_ animatingDifferences: Bool) {
var snapshot = Snapshot()
snapshot.appendSections([.MainAsEnum])
snapshot.appendItems(filteredTabInfos,toSection: .MainAsEnum)
dataSource?.apply(snapshot,animatingDifferences: animatingDifferences)
}
但是,当Section具有动态内容页脚时,我们可能需要使用struct来表示Section。例如
import Foundation
struct TabInfoSection {
// Do not include content items [TabInfo] as member of Section. If not,any mutable
// operation performed on content items,will misguide Diff framework to throw
// away entire current Section,and replace it with new Section. This causes
// flickering effect.
var footer: String
}
extension TabInfoSection: Hashable {
}
但是,我们应该如何只更新页脚?
当前提供的方法
DiffableDataSource: Snapshot Doesn't reload Headers & footers并不完全准确
如果我尝试更新页脚
class TabInfoSettingsController: UIViewController {
…
func applySnapshot(_ animatingDifferences: Bool) {
var snapshot = Snapshot()
let section = tabInfoSection;
snapshot.appendSections([section])
snapshot.appendItems(filteredTabInfos,toSection: section)
dataSource?.apply(snapshot,animatingDifferences: animatingDifferences)
}
var footerValue = 100
extension TabInfoSettingsController: TabInfoSettingsItemCellDelegate {
func crossButtonClick(_ sender: UIButton) {
let hitPoint = (sender as AnyObject).convert(CGPoint.zero,to: collectionView)
if let indexPath = collectionView.indexPathForItem(at: hitPoint) {
// use indexPath to get needed data
footerValue = footerValue + 1
tabInfoSection.footer = String(footerValue)
//
// Perform UI updating.
//
applySnapshot(true)
}
}
}
我将得到以下闪烁的结果。
之所以闪烁,是因为diff框架抛出了整个旧的Section,并用新的Section替换了它,因为它发现TabInfoSection
对象中有更改。
是否有一种好的方法,可以通过DiffableDataSource
更新Section中的页脚,而不会引起闪烁效果?
p / s整个项目源代码可以在https://github.com/yccheok/ios-tutorial/tree/broken-demo-for-footer-updating中的TabDemo文件夹下找到。
解决方法
您是否考虑过只为页脚创建部分?这样,在闪烁时就不会重新加载,因为从技术上讲,它不在有问题的部分之外?
,有一个快速修复程序,但是您将失去tableview的动画。在TabInfoSettingsController.swift中,您可以在此函数中强制设置错误动画:
/network/dependencies
您将看不到闪烁的效果,但是将失去标准动画。
,如果您只想更新collectionview页脚文本,则将其设置为TabInfoSettingsFooterCell
的变量。
var tableSection: TabInfoSettingsFooterCell?
数据源
func makeDataSource() -> DataSource {
let dataSource = DataSource(
collectionView: collectionView,cellProvider: { (collectionView,indexPath,tabInfo) -> UICollectionViewCell? in
guard let tabInfoSettingsItemCell = collectionView.dequeueReusableCell(
withReuseIdentifier: TabInfoSettingsController.tabInfoSettingsItemCellClassName,for: indexPath) as? TabInfoSettingsItemCell else {
return nil
}
tabInfoSettingsItemCell.delegate = self
tabInfoSettingsItemCell.reorderDelegate = self
tabInfoSettingsItemCell.textField.text = tabInfo.getPageTitle()
return tabInfoSettingsItemCell
}
)
dataSource.supplementaryViewProvider = { collectionView,kind,indexPath in
guard kind == UICollectionView.elementKindSectionFooter else {
return nil
}
let section = dataSource.snapshot().sectionIdentifiers[indexPath.section]
guard let tabInfoSettingsFooterCell = collectionView.dequeueReusableSupplementaryView(
ofKind: kind,withReuseIdentifier: TabInfoSettingsController.tabInfoSettingsFooterCellClassName,for: indexPath) as? TabInfoSettingsFooterCell else {
return nil
}
tabInfoSettingsFooterCell.label.text = section.footer
//set tableSection value
self.tableSection = tabInfoSettingsFooterCell
return tabInfoSettingsFooterCell
}
return dataSource
}
TabInfoSettingsItemCellDelegate
func crossButtonClick(_ sender: UIButton) {
let hitPoint = (sender as AnyObject).convert(CGPoint.zero,to: collectionView)
if let indexPath = collectionView.indexPathForItem(at: hitPoint) {
footerValue = footerValue + 1
tabInfoSection.footer = String(footerValue)
//Update section value
self.tableSection?.label.text = String(footerValue)
}
}