如何通过DiffableDataSource更新Section中的页脚而不会造成闪烁效果?

Che*_*eng 5 ios swift diffabledatasource

一个部分可能包含 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)
}
Run Code Online (Sandbox Code Playgroud)

但是,当 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 {
}
Run Code Online (Sandbox Code Playgroud)

但是,我们如何假设只更新页脚?

目前提供的方法

DiffableDataSource:快照不会重新加载页眉和页脚并不完全准确

如果我尝试更新页脚

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我会得到以下闪烁的结果。

在此处输入图片说明

闪烁的原因是diff框架抛出整个旧Section,并用新Section替换它,因为它发现TabInfoSection对象发生了变化。

有没有好的方法,通过更新节中的页脚DiffableDataSource而不会引起闪烁效果?

p/s 整个项目源代码可以在https://github.com/yccheok/ios-tutorial/tree/broken-demo-for-footer-updating文件夹 TabDemo 下找到。

Jay*_*Jay 2

您是否考虑过只为页脚创建一个部分?这样,当它闪烁时就不会重新加载,因为它在技术上不属于有问题的部分?