'TableView scrolling to top after applying UITableViewDiffableDataSource snapshot

I'm doing pagination using UITableViewDataSourcePrefetching.

The values will be taken from the Realm local storage.

I will get an array of objects. These values will be applied to the existing UITableViewDiffableDataSource datasource.

After applying snapshot the tableview scrolling to the top.

I have verified that all my ChatMessage objects has unique hashValues.

How can I prevent the scrolling?

Link to the video TableView_scroll_issue_video

Given my code snippet

private func appendLocal(chats chatMessages: [ChatMessage]) {
    var sections: [String] = chatMessages.map({ $0.chatDateTime.toString() })
    sections.removeDuplicates()
    guard !sections.isEmpty else { return }
    var snapshot = dataSource.snapshot()
    let chatSections = snapshot.sectionIdentifiers
    sections.forEach { section in
        let messages = chatMessages.filter({ $0.chatDateTime.toString() == section })
        /// Checking the section is already exists in the dataSource
        if let index = chatSections.firstIndex(of: section) {
            let indexPath = IndexPath(row: 0, section: index)
            /// Checking dataSource already have some messages inside the same section
            /// If messages available then add the recieved messages to the top of existing messages
            /// else only section is available so append all the messages to the section
            if let item = dataSource.itemIdentifier(for: indexPath) {
                snapshot.insertItems(messages, beforeItem: item)
            } else {
                snapshot.appendItems(messages, toSection: section)
            }
        } else if let firstSection = chatSections.first {
            /// Newly receieved message's section not available in the dataSource
            /// Add the section before existing section
            /// Add the messages to the newly created section
            snapshot.insertSections([section], beforeSection: firstSection)
            snapshot.appendItems(messages, toSection: section)
        } else {
            /// There is no messages available append the new section and messages
            snapshot.appendSections([section])
            snapshot.appendItems(messages, toSection: section)
        }
    }
    dataSource.apply(snapshot, animatingDifferences: false)
}


Solution 1:[1]

You can try the following:

dataSource.applySnapshotUsingReloadData(snapshot, completion: nil)

It's only available from iOS 15.0

Also common mistake is using UUID().uuidString.
Make sure that the id of each cell is fixed. UITableViewDiffableDataSource will not be able to properly calculate changes and it will reload the whole table if ids are updated.

Solution 2:[2]

You can try creating a new snapshot instead of referencing & mutating the current snapshot of your dataSource.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 NikoPich