Alex Popov Alex Popov - 3 months ago 44x
iOS Question

Nested UIStackViews Broken Constraints

I have a complex view hierarchy, built in Interface Builder, with nested UIStackViews. I get "unsatisfiable constraints" notices every time I hide some of my inner stackviews. I've tracked it down to this:

"<NSLayoutConstraint:0x1396632d0 'UISV-canvas-connection' == UILabel:0x13960cd30'Also available on iBooks'.top>",
"<NSLayoutConstraint:0x139663470 'UISV-canvas-connection' V:[UIButton:0x139554f80]-(0)-| (Names: '|':UIStackView:0x1392c5020 )>",
"<NSLayoutConstraint:0x139552350 'UISV-hiding' V:[UIStackView:0x1392c5020(0)]>",
"<NSLayoutConstraint:0x139663890 'UISV-spacing' V:[UILabel:0x13960cd30'Also available on iBooks']-(8)-[UIButton:0x139554f80]>"

Specifically, the
constraint: when hiding a UIStackView its high constraint gets a 0 constant, but that seems to clash with the inner stackview's spacing constraint: it requires 8 points between my Label and Button, which is irreconcilable with the hiding constraint and so the constraints crash.

Is there a way around this? I've tried recursively hiding all the inner StackViews of the hidden stack view, but that results in strange animations where content floats up out of the screen, and causes severe FPS drops to boot, while still not fixing the problem.


Ideally we could just set the priority of the UISV-spacing constraint to a lower value, but there doesn't appear to be any way to do that. :)

I am having success setting the spacing property of the nested stack views to 0 before hiding, and restoring to the proper value after making it visible again.

I think doing this recursively on nested stack views would work. You could store the original value of the spacing property in a dictionary and restore it later.

My project only has a single level of nesting, so I am unsure if this would result in FPS problems. As long as you don't animate the changes in spacing, I don't think it would create too much of a hit.