Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update footer in Section via DiffableDataSource without causing flickering effect?

A Section may contain 1 header, many content items and 1 footer.

For DiffableDataSource, most of the online examples, are using enum to represent Section. For instance

func applySnapshot(_ animatingDifferences: Bool) {
    var snapshot = Snapshot()
    
    snapshot.appendSections([.MainAsEnum])

    snapshot.appendItems(filteredTabInfos, toSection: .MainAsEnum)

    dataSource?.apply(snapshot, animatingDifferences: animatingDifferences)
}

However, when the Section has a dynamic content footer, we may need to use struct to represent Section. For instance

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 {
}

But, how are we suppose to update only footer?

The current approach provided by

DiffableDataSource: Snapshot Doesn't reload Headers & footers is not entirely accurate

If I try to update footer

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)
        }
    }
}

I will get the following flickering outcome.

enter image description here

The reason of flickering is that, the diff framework is throwing entire old Section, and replace it with new Section, as it discover there is change in TabInfoSection object.

Is there a good way, to update footer in Section via DiffableDataSource without causing flickering effect?

p/s The entire project source code can be found in https://github.com/yccheok/ios-tutorial/tree/broken-demo-for-footer-updating under folder TabDemo.

like image 614
Cheok Yan Cheng Avatar asked Oct 16 '22 00:10

Cheok Yan Cheng


1 Answers

Have you thought about making a section only for the footer? So that way there's no reload, when it flickers, since it's technically not apart of the problematic section?

like image 168
Jay Avatar answered Nov 15 '22 13:11

Jay