iosswiftuitableviewautolayoutuitableviewautomaticdimension

UITableViewCell expanding animation with self-sizing labels, visual animation problem


I've got a problem with self-sizing and animatable table view cells, with the animation part only.

The issue is that when the cell expands, 2 of the labels are overlapped as the other items expand. If you look at the gif below, the top label "370 Base Axle Ratio" becomes overlapped by the middle elements. Those middle elements slide down as a group, which is also undesirable, and if you look closely, the "0" under the words in the middle "Original Production" is also overlapped and it expands or is revealed incorrectly.

The top bold label "370 Base Axle", is set to be 0 lines of text so it can expand to fit multiple lines. The center group of labels is anchored to the bottom of that label. The bottom long text label is anchored to the bottom of the middle "0" label.

If I anchor the middle group of items to the top of the view at a fixed amount, then the expansion works without the overlap effect, but of course this breaks the dynamic nature of having multiple lines of text in that top label.

This layout is built with auto-layout, but is not using stack views (and is not my preferred solution at this time).

No specific code is used to set any layout sizes, only using this in the tableViewController after I add or remove the text in the bottom label:

tableView.beginUpdates()
tableView.endUpdates()

How would I fix this so the ONLY element that would expand is the bottom most label with the long amount of text, but still have a variable label height at the top?

TL;DR: Labels with multiple lines of text breaks animation when other multi-line labels are animated in a "show more" style of expanding table cell.

enter image description here


Solution

  • You can almost fix your issues with very few changes.

    Two important things:

    Couple drawbacks to your method of setting / clearing the text of the label though. The expand animation will work well, but the collapse animation will look as it does in your original gif --- the text disappears instead of being covered. Also, you have extra spacing at the bottom.

    To get around that, you can set a constraint from the bottom of the "description" label - as you likely have it now - to the bottom of the content view... this will be the "expanded" constraint, AND add another constraint from the bottom of the "center 0" label to the bottom of the content view... this will be the "collapsed" constraint.

    Those constraints will conflict at first... so change the Priority of the one of those constraints (doesn't matter which) to 750 (Default High) and the other constraint to 250 (Default Low).

    When your app is running, you would swap the priorities based on whether you want the cell expanded or collapsed.

    I put together a sample app using your layout - You can download it here: https://github.com/DonMag/Maverick

    I use background colors to make it easy to see the frames. There is a line in cellForRowAt that can be un-commented to clear the colors.

    The result using your set / clear text approach:

    and using the Constraints method: