When my UIStackView "rows" are squished, they throw AutoLayout
warnings. However, they display fine and nothing else is wrong besides these sorts of loggings:
Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing
NSAutoresizingMaskLayoutConstraints
that you don't understand, refer to the documentation for theUIView
propertytranslatesAutoresizingMaskIntoConstraints
) (
So, I'm not sure how to fix this yet, but it doesn't seem to break anything besides just being annoying.
Does anyone know how to solve it? Interestingly, the layout constraints are tagged quite often with 'UISV-hiding', indicating that perhaps it should ignore the height minimums for subviews or something in this instance?
You get this issue because when setting a subview from within UIStackView
to hidden, it will first constrain its height to zero in order to animate it out.
I was getting the following error:
2015-10-01 11:45:13.732 <redacted>[64455:6368084] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSLayoutConstraint:0x7f7f5be18c80 V:[UISegmentedControl:0x7f7f5bec4180]-(8)-| (Names: '|':UIView:0x7f7f5be69d30 )>", "<NSLayoutConstraint:0x7f7f5be508d0 V:|-(8)-[UISegmentedControl:0x7f7f5bec4180] (Names: '|':UIView:0x7f7f5be69d30 )>", "<NSLayoutConstraint:0x7f7f5bdfbda0 'UISV-hiding' V:[UIView:0x7f7f5be69d30(0)]>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7f7f5be18c80 V:[UISegmentedControl:0x7f7f5bec4180]-(8)-| (Names: '|':UIView:0x7f7f5be69d30 )> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
What I was trying to do, was to place a UIView
within my UIStackView
that contained a UISegmentedControl
inset by 8pts on each edge.
When I set it to hidden, it would try to constrain the container view to a zero height but because i have a set of constraints from top to bottom, there was a conflict.
To resolve the issue, I changed my 8pt top an bottom constraints priority from 1000 to 999 so the UISV-hiding
constraint can then take priority if needed.
I was having a similar problem that wasn't easy to resolve. In my case, I had a stack view embedded in a stack view. The internal UIStackView had two labels and a non-zero spacing specified.
When you call addArrangedSubview() it will automatically create constraints similar to the following:
V:|[innerStackView]| | = outerStackView V:|[label1]-(2)-[label2]| | = innerStackView
Now when you try to hide the innerStackView, you get an ambiguous constraints warning.
To understand why, let's first see why this doesn't happen when innerStackView.spacing
is equal to 0
. When you call innerStackView.hidden = true
, @liamnichols was correct... the outerStackView
will magically intercept this call, and create a 0
height UISV-hiding constrain with priority 1000 (required). Presumably this is to allow elements in the stack view to be animated out of view in case your hiding code is called within a UIView.animationWithDuration()
block. Unfortunately, there doesn't seem to be a way to prevent this constraint from being added. Nevertheless, you won't get an "Unable to simultaneously satisfy constraints" (USSC) warning, since the following happens:
It's clear to see that those 4 constraints can be satisfied. The stack view simply smooshes everything into a 0-height pixel.
Now going back to the buggy example, if we set the spacing
to 2
, we now have these constraints:
The stack view cannot both be 0 pixels high and have its contents be 2 pixels high. The constraints cannot be satisfied.
Note: You can see this behavior with a simpler example. Simply add a UIView to a stack view as an arranged subview. Then set a height constraint on that UIView with 1000 priority. Now try calling hide on that.
Note: For whatever reason, this only happened when my stack view was a subview of a UICollectionViewCell or UITableViewCell. However, you can still reproduce this behavior outside of a cell by calling innerStackView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
on the next run loop after hiding the inner stack view.
Note: Even if you try executing the code in a UIView.performWithoutAnimations, the stack view will still add a 0 height constraint which will cause the USSC warning.
There are at least 3 solutions to this problem:
spacing
to 0. This is annoying because you need to reverse the process (and remember the original spacing) whenever you show the content again.removeFromSuperview
. This is even more annoying since when you reverse the process, you need to remember where to insert the removed item. You could optimize by only calling removeArrangedSubview and then hiding, but there is a lot of bookkeeping that still needs to be done.spacing
) in a UIView. Specify at least one constraint as non-required priority (999 or below). This is the best solution since you don't have to do any bookkeeping. In my example, I created top, leading, and trailing constraints at 1000 between the stack view and the wrapper view, then created a 999 constraint from the bottom of the stack view to the wrapper view. This way when the outer stack view creates a zero height constraint, the 999 constraint is broken and you don't see the USSC warning. (Note: This is similar to the solution to Should the contentView.translatesAutoResizingMaskToConstraints of a UICollectionViewCell subclass be set to false
)In summary, the reasons you get this behavior are:
Had Apple either (1) allowed you to specify the priority of constraints (especially of spacers), or (2) allowed you to opt-out of the automatic UISV-hiding constraint, this problem would be easily resolved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With