Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can UITableViewDiffableDataSource detect an item changed?

(The question was rewritten after discussing with @AndreasOetjen below. Thanks for his comments.)

I ran into an issue with using UITableView with diffable data source. In my app when user modifies an item, it may change another item which is shown in the same table view. The issue is that, after I created and applied a new snapshot containing both items' new values, the indirectly changed item's UI wasn't updated.

At first I thought diffable data source was able to detect an item's value change in different snapshot. For example, it might work this way: if it found both snapshots contains the same item (that is, items in both snapshots have same hash value), it compared their values and updated that item's row in table view if value changed. However, I later realized it perhaps didn't work that way because diffable data source doesn't define any API to get and compare item value (my original thought was it used description computed property and == operation, but now I believe it's not true).

So my current understanding is diffable data source uses item's hash for detecting item order change (i.e., new item inserted, an old item still existed, etc.), instead of item value change (i.e., an old item still existed but its value changed). If that understanding is correct, it then begs this question: how to use diffable data source to implement the following scenario?

  • An item has several properties. One property (let's call it property A) is shown in UI but is not used for generating hash.
  • The item exists in both old and new snapshots, but its property A changes. So its UI needs to be updated.

In the old UITableView API, this can be implemented by calling reloadRows() or reloadData(). But how to do it using diffable data source?

UPDATE:

After spending time doing experiments and solving the issue, I believe the understanding in above question was incorrect. Please see my answer below. I believe that explains how diffable data source works. I hope it helps to others who'll have the same confusion. I'd be glad to be proved wrong. Really. So please leave your answer if you think differently.

like image 221
rayx Avatar asked Apr 07 '20 05:04

rayx


People also ask

How do you update a Diffable data source?

The only mechanism to update the data for existing items is to apply a new snapshot containing the new data structures, which causes the diffable data source to perform a delete and an insert for each changed item.

What is a Diffable data source?

A diffable data source object is a specialized type of data source that works together with your table view object. It provides the behavior you need to manage updates to your table view's data and UI in a simple, efficient way.


1 Answers

After almost one day's clueless experiments, I believe I figured out how diffable data source worked and solved my issue based on that understanding (it turned out my original thought was almost correct).

Diffable data source uses item hash to identify item. For the same item that exists in both old and new snapshots, diffable data source checks if the item changes by doing an "==" operation with its old and new values.

Once figured out, it looks like quite obvious and simple approach. But it's so fundamental that I can't understand why it isn't mentioned explicitly anywhere.

So, to answer my original question, yes, diffable data source can detect item value change. That said, it becomes tricky when item value is of reference type and/or the text shown in row is, say, properties of objects referenced by that object (e.g., relationship in Core Data), etc.

Another note. Whether using entire item struct or just part of it to generate item hash doesn't matter, as long as it identifies the item. I prefer to using only the essential part of the item which really identifies it.

like image 179
rayx Avatar answered Sep 28 '22 03:09

rayx