Update to UITableViewDiffableDataSource row

When an instance var of an object changes value then the new state is not shown by the UITableView with a UITableViewDiffableDataSource after the call to dataSource.apply(snapshot).


Is there a way for an update/change flag to work on objects in a UITableViewDiffableDataSource?


This is mentioned in the https://forums.developer.apple.com/thread/120320 where developers found that changes in fields do not show as the uniqueIdentifiers have not changed in the object.


I have found that the object with a instance var change must be deleted from the items in the datasource.snapshot and added with a new unique identifier. Here's some psuedo code to illustrate the behaviour


var snapshot = dataSource.snapshot()
updateItem = dataSource.itemIdentifier(for: changedRow)

updateItem.stateVar = true

dataSource.apply(snapShot)


The new state is not shown in the UI


Instead to make the new state show I have to remove the old item, copy to a new instance with a new unique identifier, update the state. Then remove the old item from the snapshot and insert the new item.


Clearly creating a complete new snapshot instead of copy/change of the existing snapshot would show the new object state. However when only one row of a large dataSource is changed there is a performance problem.


Psuedo code that makes the new state show


var snapshot = dataSource.snapshot()
updateItem = dataSource.itemIdentifier(for: changedRowPath)

updateItem.stateVar = true

// make a copy of the updateItem with a new uniqueIdentifier
newbieItem = updateItem.clone() 

// now get the postion prior item in the snapshot     
priorRow = max(changedRowPath.row - 1, 0)
priorItemIndex = IndexPath(row: priorRow, section: changeRowPath.section)
priorItem = dataSource.itemIdentifier(for: priorItemIndex)

// delete updateItem
snapshot.deleteItems([updateItem]
snapshot.insertItems([newbieItem], afterItem: priorItem)
// now apply with new clone and the changed value
dataSource.apply(snapShot

Did I miss a simple way to change one row of a dataSource? Or how should this be handled?

Replies

After a nice discussion at a WWDC 2020 lab the solution has been found. And yes I did miss the simple way.. oh well, live and learn.
The answer is that uiState is cached and the dataSource needs to be notified of the change.

The missing line after updateItem.stateVar = true

snapshot.reloadItems([updateItem])

Now apply the change
dataSource.apply(snapshot)

thank you Apple engineer !
Will