3

I'm having layout issues with my horizontal UIStackView in a custom UITableViewCell when showing/hiding arrangedSubviews when the horizontalSizeClass changes.

My stack view contains a number of subviews, each of which, depending on cell configuration and size class, are either hidden or shown. The UIStackView is designed to handle arranging the shown views, but upon rotation, layout issues arise.

Issues:

  • Sometimes, the appropriate subviews are either not shown or not hidden when they ought to be.
  • Sometimes, the subviews are inappropriately laid out, not filling the stack view's width.

Attempts:

I've attempted a number of things to address the layout:

  • Overriding viewWillTransitionToSize:transitionCoordinator to reload the table and/or force layout
  • Overriding viewWillTransitionToTraitCollection:withTransitionCoordinator to reload the table and/or force layout
  • Overriding layoutSubviews to re-configure the stack view's arrangedSubviews
  • Calling [self setNeedsLayout], [self layoutIfNeeded] after configuring the cell
  • Forcing layout in other places
  • Changing subview layout constraint priorities to 999
  • Limiting the UILabels to 1 line, and setting a preferredMaxLayoutWidth
  • Adjusting the contentCompressionResistance and contentHuggingPriority on views
  • Using a static value for rowHeight instead of UITableViewAutomaticDimension
  • Etc.

Nothing appears to fix the issues.

Furthermore, even when cells are scrolled off/on screen, prepared for reuse, and re-configured, issues either persist, go away, or new issues are introduced, despite the fact that I'm properly resetting the cell on prepareForReuse.


Sample Project

I've created a sample project to illustrate the layout issues. At this point, I'm unsure if UIStackView is buggy or if I'm misusing it.

Sample Project: https://github.com/bradgmueller/StackViewTest

The sample project uses a custom UITableViewCell with views configured in the xib. Row objects are generated with different configurations to illustrate the dynamic layouts the cell should adopt:

  • Indented / not indented
  • Showing separator or not
  • Showing / hiding a "like" button
  • Showing / hiding a "Share" button
  • Showing / hiding an Info button, where one info button exists for UIUserInterfaceSizeClassCompact and another for UIUserInterfaceSizeClassRegular

A text label exists with text indicating which of the views ought to be displayed, to help illustrate when views are inappropriately shown/hidden. Also, a red background view exists behind the UIStackView to illustrate when the stack view is failing to Fill the width.

Screenshots:

Initial layout - no issues Initial layout - no issues

After rotating - issues marked with red "X" Rotation - issues arise


I'd appreciate any insight, thanks in advance!!

beebcon
  • 6,893
  • 5
  • 25
  • 27

1 Answers1

0

Generally stack views are pretty good, but when they get more complicated and manage more views, they appear to be less reliable.

I found that the best way to avoid the layout issues is to do one or two things:

  1. Use multiple stack views. Instead of bunching all of my views into the same stack view, having multiple smaller stack views seems to be more reliable, as each is managing fewer views.
  2. Remove / Re-insert views, rather than hide them. Though stack views are supposed to treat "hidden" views as if they are removed from the hierarchy, I got much better layout results when I actually removed them from the hierarchy.

Ex:

More reliable layout results:

if (hideSubview == YES) {
    [subview removeFromSuperview];
} else {
    [stackView insertArrangedSubview:subview atIndex:0];
}

Not as reliable:

subview.hidden = hideSubview;
beebcon
  • 6,893
  • 5
  • 25
  • 27