UIListContentConfiguration: Cell not showing updated text

I created a UIListContentConfiguration, set the initial text and set it on the cell. Then I updated the text and was expecting the cell to show the new text and sadly that didn't happen. Here is some sample code:

Code Block
- (void)configureCell:(UITableViewCell *)cell withEvent:(Event *)event {
UIListContentConfiguration *content = cell.defaultContentConfiguration;
content.text = event.timestamp.description;
cell.contentConfiguration = content;
[self performSelector:@selector(updateTest:) withObject:content afterDelay:3];
}
- (void)updateTest:(UIListContentConfiguration *)content{
content.text = @"Updated text";
}


Then I noticed that cell.contentConfiguration is a copy property type. Perhaps the API could be improved to change it to a strong property type, and have the cell do KVO on the configuration's text so we can update afterwards and the cell will automatically update to the new text. The same way as how MKAnnotation and MKAnnotationView works for its coordinate, title and subtitle.
As you noted, in Objective-C the property has the copy attribute, so once you have applied the configuration to a cell, making more changes to the configuration itself won't affect what the cell is rendering, as those changes are only affecting your local copy. You can re-apply the configuration to the cell again if you want to "commit" those changes.

This is an intentional design decision for this API: as discussed in the Modern Cell Configuration session from WWDC20, content and background configurations are designed to be values, and making changes to a configuration works a bit differently than setting properties on a UIView directly. By applying the entire configuration to the cell at once, your cell is never in a partially-configured state: it transitions "atomically" from one configuration to another, which ensures that there's a single source of truth for how your cell is configured at any point in time. And by receiving the entire configuration at once, the cell is able to transition from the old configuration in the most efficient way, which improves performance.

Configurations are lightweight, and are intended to be short-lived; instead of holding on to a configuration for a while and trying to update it or apply it to a cell later, when you want to make a change, you should always request a fresh configuration and set it up as desired. When using configurations, the best pattern is to choose a single place in your code that is responsible for setting up the configuration and applying it to your cell, and simply re-run that code anytime you need to update the cell. The updateConfiguration(using state:) method in your cell subclass is a great choice for this.
It all sounds good in theory but in practice this design of atomic updates doesn't work. We cannot update the text without losing the entire state fo the cell. E.g. if the cell has been swiped to show the delete button. Then if we need to update the text (because of a background update for example) when we set a new configuration the swiped state is also lost. The cell is left in an inconsistent state - it's indented but the delete button has disappeared.

I suppose we could retrieve the current state from the cell, update it and then set it again on the cell. But it would be much simpler if the cell just listened for changes to the configuration object, as I attempted in the code in my question.

I submitted a feedback about this FB7977764
Thanks for submitting feedback about this.

The behavior you're seeing where the swipe actions (delete button) disappear when you perform batch updates on the table view (using beginUpdates and endUpdates) is just a bug in the current iOS 14 beta. Rest assured that this will be fixed in a future beta and will work the way you expect it to.

Aside from this known issue, the usage in the sample project attached to your feedback looks correct.
UIListContentConfiguration: Cell not showing updated text
 
 
Q