Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableViewDiffableDataSource Invalid sections

Tags:

uikit

I try to use UITableViewDiffableDataSource

class SecondViewController: UIViewController {

    enum Section {
        case main
    }

    struct Model: Hashable {
        let title: String
    }

    var tableView: UITableView!
    var dataSource: UITableViewDiffableDataSource<Section, Model>!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView = UITableView(frame: view.bounds)
        view.addSubview(tableView)
        tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")

        view.layoutIfNeeded()

        dataSource = UITableViewDiffableDataSource<Section, Model>(tableView: tableView, cellProvider: { (tableView, indexPath, item) -> UITableViewCell? in
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            cell.textLabel?.text = item.title
            return cell
        })

        var snapshot = NSDiffableDataSourceSnapshot<Section, Model>()
        snapshot.appendSections([.main])
        snapshot.appendItems([Model(title: "1")], toSection: .main)
        dataSource.apply(snapshot)
    }
}

if I use view.layoutIfNeeded() before create dataSource, it will crash:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (1) must be equal to the number of sections contained in the table view before the update (1), plus or minus the number of sections inserted or deleted (1 inserted, 0 deleted).'

like image 862
KelaKing Avatar asked Mar 21 '20 15:03

KelaKing


1 Answers

I encountered the same problem, when populating a UITableView with results from a PassthroughSubject, as soon as the UIViewController was displayed.

Animating updates was very important to me, so my workaround was to first "prime" the DiffableDataSource by creating a snapshot immediately after initialisation, appending the sections I wanted, appending the items with an empty array, and applying the snapshot with animatingDifferences: false.

Afterwards I was able to apply animated snapshots with data with no issue.

like image 194
Michael Tigas Avatar answered Nov 02 '22 22:11

Michael Tigas