Autolayout unable to satisfy constraints that do not appear to conflict [duplicate] - ios

I have a custom UITableViewCell which has a thumbnail and bunch of text. The row height is configured to be calculated automatically using
tableView.estimatedRowHeight = 129;
tableView.rowHeight = UITableViewAutomaticDimension
The row height should be calculated as exactly 138 points.
Everything looks great on the iPhone 5. However, on iPhone 6 Plus, the auto row height fails INTERMITTENTLY for random rows with the following log.
(
"<NSLayoutConstraint:0x17009ddd0 V:|-(20)-[scoop.ThumbnailImage:0x124d2a5a0] (Names: '|':UITableViewCellContentView:0x124e23200 )>",
"<NSLayoutConstraint:0x17009de70 UITableViewCellContentView:0x124e23200.bottomMargin == scoop.ThumbnailImage:0x124d2a5a0.bottom + 20>",
"<NSLayoutConstraint:0x17009e780 V:[scoop.ThumbnailImage:0x124d2a5a0(90)]>",
"<NSLayoutConstraint:0x17009ef00 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x124e23200(138.333)]>"
)
The last line of the log seems to say that for some reason the row height was calculated as 138.333 instead of 138. I have been banging my head for a while now but I am unable to figure out why this is happening. Can some one please help?
Update: This is how my table view cell looks like.
UPDATE I couldn't get the code out of the main repo since its a part of a bigger project. But I have managed to reproduce the issue with a very simple sane project. Please find it here on github.

This warning is telling you there's a conflict in your constraints.
Reduce the priority of the height constraint to 999 and it will go away. Tested it in your Github project and worked perfectly.

0.333 on a 3x scale display (which iPhone 6+ is) is probably connected with the cell separator.
Note that your constraints don't set up the size of the cell, they set up the size of the contentView. But the cell has to add 2 pixels (= 0.666 points) to the cell height for the cell separator. Autolayout tries to keep view positions on integer boundaries so adding 0.666points to the cell height can result in adding 0.333 to your content height.
You can avoid the error by setting your table separators to None. Although setting up one of the priorities to 999 (usually the bottom priority) as the other answer has suggested is a good solution in general.

The warning is telling you exactly what the problem is, but you may not realize it. The first three constraints are for a 90 pixel-high image that's 20 pixels below the top of its container, and 20 pixels above its container's bottom margin. That's 130, and that's not compatible with the fourth constraint, which wants a total height of 138. However, because the bottom edge constraint is relative to the container's margin, that adds a certain number of pixels more. Either remove the total height constraint (my recommendation), or change the top and bottom edge amounts.

Related

Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want

I have a custom xib file and am trying to load a picture when the table view is launched. However I get this error of multiple constraints. I have set the row height of the tableviewcell automatic, and the sum of three views that comprise the xib view add up to 408 pixels. I have also tried setting the row height to 409 given the error said 408.333 pixels for the cell, however this did not help.
This is a common issue, particularly when using UIStackViews in table view cells.
The problem is that as auto-layout is "doing its thing," it has to make several passes to calculate the complete layout.
When it encounters a stack view in a (non-fixed-height) cell, it needs to deal with the various heights of the stackView's arranged subviews, the table width and height, and the cell height. In addition, because a point on a #2x scale device uses 2 pixels, and on a #3x scale device it uses 3 pixels, auto-layout has to manipulate heights around one-half-points and one-third-points, respectively.
I think I would say it's not surprising that at some point during those calculations auto-layout prints error / warning messages to the console.
Setting the Priority on the stack view's Bottom constraint to 999 allows auto-layout to, I guess, temporarily break the constraint without coughing up the warning.
So... is it a Bug? Or is it Unavoidable? Only Apple knows for sure. :)

UIlabel trailing space not working

I have a label in a tableview cell with several constraints in Interface builder.
The cell is self sizing and thats working fine.
My problem is, that the "trailing space" constraint is not working.
The text is not broken and goes to far to the right - out of the screen.
I dont understand this. If someone could help me out, what be fantastic, because I am now searching for hours and dont find the root cause.
The Label is set to 0 lines by:
cell.commentLabel?.numberOfLines = 0
http://picpaste.com/p1-AmKNGkwx.jpg
http://picpaste.com/p2-7ODUyyoc.jpg
The problem is that you're setting a fixed size (600 x 444 - based on your comments above) on your tableview, which is larger than the logical resolution of the width for most devices and this causes the cells to expand beyond the visible area.
So, you must remove the fixed constraints and add some relative ones (for example match the width of the superview & set the bottom of the tableview to the top of your 'footer' - or whatever makes sense in your case... you can even stick with the hardcoded 444 for its height - the width is the important one here)

NSLayoutConstraint breaks

I have a custom UITableViewCell. The cell has three labels. The left most 'Amount' Label has the following constraint.
On the right side of the cell I have another label, 'Label Dollar Amount'. It has the following constraints:
The third label is right below 'Label Dollar Amount' is the 'Label Max Amount'. The constraints are as follows:
Nothing is done on the code. The table row height is calculated using UITableViewAutomaticDimension. The estimatedRowHeight is set to 100.
When the view is in landscape and the tableview is scrolled down, this particular cell is being dequeued since its out of the visible view. When the orientation is changed to portrait for the same state, the cell is expected to be visible.
I receive the following error:
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:0x1607a770 H:[UILabel:0x160c1990'Amount'(150)],
NSLayoutConstraint:0x160c2b30 H:|-(18)-[UILabel:0x160c1990'Amount'] (Names: '|':UITableViewCellContentView:0x160c18c0 ),
NSLayoutConstraint:0x160c2b90 H:[UILabel:0x160c1990'Amount']-(0)-[UILabel:0x160c1c40'$45.61'],
NSLayoutConstraint:0x160c2bf0 UILabel:0x160c1ac0'(Max: $1,000.00)'.leading == UILabel:0x160c1c40'$45.61'.leading,
NSLayoutConstraint:0x160c2c80 H:[UILabel:0x160c1ac0'(Max: $1,000.00)']-(12)-| (Names: '|':UITableViewCellContentView:0x160c18c0 ),
NSLayoutConstraint:0x14e179e0 'UIView-Encapsulated-Layout-Width' H:[UITableViewCellContentView:0x160c18c0(72)]
)
Will attempt to recover by breaking constraint
NSLayoutConstraint:0x1607a770 H:[UILabel:0x160c1990'Amount'(150)]`
Note: Priorities are set to 1000 (Required) for all possible constraints seen here.
If I change the priority of the width constraint on Amount label to 999 it works. But the label disappears for longer text. Since zero spacing in the trailing constraint has a hight priority. Any suggestion on what could have gone wrong?
The table is setting a fixed width of 72 points on your cell view. This may just be temporary while it adjusts to the new orientation or layout, but you need to accommodate it:
NSLayoutConstraint:0x14e179e0 'UIView-Encapsulated-Layout-Width' H:[UITableViewCellContentView:0x160c18c0(72)]
So, you need to decide what should happen in your layout when its superview is only 72 points wide.
Currently, you have the following (edited a bit to make things clearer):
H:|-(18)-[UILabel:0x160c1990'Amount'] (Names: '|':UITableViewCellContentView:0x160c18c0 ),
H:[UILabel:0x160c1990'Amount'(150)],
H:[UILabel:0x160c1990'Amount']-(0)-[UILabel:0x160c1c40'$45.61'],
UILabel:0x160c1ac0'(Max: $1,000.00)'.leading == UILabel:0x160c1c40'$45.61'.leading,
H:[UILabel:0x160c1ac0'(Max: $1,000.00)']-(12)-| (Names: '|':UITableViewCellContentView:0x160c18c0 ),
Or:
H:|-(18)-[Amount(150)][Max]-(12)-|
So, even if every view which could be collapsed to 0 width were, you would still require 18 + 150 + 12 == 180 points of width between the edges of the superview. That conflicts with the 72 points available.
How would you like that to be resolved? One possibility is to reduce the priority of the width constraint on the Amount label, as you mention. Or you could even eliminate this constraint entirely and rely on the intrinsic width and the compression resistance priority. You say "the label disappears for longer text. Since zero spacing in the trailing constraint has a hight priority." I'm not entirely sure what you mean. Perhaps with longer text, the label is wrapping and words are on a second line which isn't visible? If so, you can set it to truncate (although that should be the default). If even truncation isn't acceptable, then what should happen?
You can try setting adjustsFontSizeToFitWidth and minimumScaleFactor to allow the text in the label to shrink, but eventually you still hit the limit (if the text is long enough and the cell width is narrow enough), so you still need to decide what you want to happen.
Another approach is to reduce the priority of the trailing constraint between Label Max Amount and the superview, so that that label moves off the right side. You may also need to reduce the priority of the trailing constraint of Label Dollar Amount, too, since it imposes the same requirement on the layout.
But, of course, that means that some of your content is off-screen. There's just no getting around the fact that you have to decide what should be lost when the width is too small to fit everything.
Once you decide what should happen, you set the priorities to achieve that. For example, if you want the Max Amount to truncate first, set its compression resistance lowest. If you want Dollar amount to truncate next, set its compression second lowest. If you want the Amount label to truncate after that, set its width constraint (or compression resistance, if you get rid of the width constraint) third lowest. And if you want things to be pushed off the right edge as a last resort, set the priority of the trailing-to-superview constraints to 999.

UITableView auto resizing row constraint breaking mysteriously on iPhone 6Plus

I have a custom UITableViewCell which has a thumbnail and bunch of text. The row height is configured to be calculated automatically using
tableView.estimatedRowHeight = 129;
tableView.rowHeight = UITableViewAutomaticDimension
The row height should be calculated as exactly 138 points.
Everything looks great on the iPhone 5. However, on iPhone 6 Plus, the auto row height fails INTERMITTENTLY for random rows with the following log.
(
"<NSLayoutConstraint:0x17009ddd0 V:|-(20)-[scoop.ThumbnailImage:0x124d2a5a0] (Names: '|':UITableViewCellContentView:0x124e23200 )>",
"<NSLayoutConstraint:0x17009de70 UITableViewCellContentView:0x124e23200.bottomMargin == scoop.ThumbnailImage:0x124d2a5a0.bottom + 20>",
"<NSLayoutConstraint:0x17009e780 V:[scoop.ThumbnailImage:0x124d2a5a0(90)]>",
"<NSLayoutConstraint:0x17009ef00 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x124e23200(138.333)]>"
)
The last line of the log seems to say that for some reason the row height was calculated as 138.333 instead of 138. I have been banging my head for a while now but I am unable to figure out why this is happening. Can some one please help?
Update: This is how my table view cell looks like.
UPDATE I couldn't get the code out of the main repo since its a part of a bigger project. But I have managed to reproduce the issue with a very simple sane project. Please find it here on github.
This warning is telling you there's a conflict in your constraints.
Reduce the priority of the height constraint to 999 and it will go away. Tested it in your Github project and worked perfectly.
0.333 on a 3x scale display (which iPhone 6+ is) is probably connected with the cell separator.
Note that your constraints don't set up the size of the cell, they set up the size of the contentView. But the cell has to add 2 pixels (= 0.666 points) to the cell height for the cell separator. Autolayout tries to keep view positions on integer boundaries so adding 0.666points to the cell height can result in adding 0.333 to your content height.
You can avoid the error by setting your table separators to None. Although setting up one of the priorities to 999 (usually the bottom priority) as the other answer has suggested is a good solution in general.
The warning is telling you exactly what the problem is, but you may not realize it. The first three constraints are for a 90 pixel-high image that's 20 pixels below the top of its container, and 20 pixels above its container's bottom margin. That's 130, and that's not compatible with the fourth constraint, which wants a total height of 138. However, because the bottom edge constraint is relative to the container's margin, that adds a certain number of pixels more. Either remove the total height constraint (my recommendation), or change the top and bottom edge amounts.

Please explain the following auto layout behavior to me

I'm currently trying to figure out what I am doing wrong with the following constraint-based UITableViewCell layout (iOS 8).
My cell is laid out as shown in this image:
There is an image view on the left, a label on the right, and both should be touching the cell margins everywhere. The image has a fixed size (64x64), the label's height will always be smaller than that. I want the image's height to cause the cell to expand the height to the correct value (image height + 2 * margin).
The problem is this: I have three constraints for the vertical size, V[Image(64)], Reset.bottom == UITableViewCellContentView.bottomMargin and Reset.top == UITableViewCellContentView.topMargin (all defined via the storyboard). When I display the cell, I get an unsatisfiable constraints error. The UIView-Encapsulated-Layout-Height constraint interferes with my constraints, and auto layout breaks my image view height constraint. Everything looks as it should, but I don't like errors at runtime.
If I give my height constraint the priority 999, everything looks fine, no errors.
So my understanding is, that my height constraint will be broken in both cases at runtime.
But when I delete the height constraint altogether, the image displays at its original height (the file has different resolution than what I display in the cell). Why is this, or what am I getting wrong here?
Edit/Update: I just noticed I was wrong about everything working. The initial display of my cell is fine, but when the cell changes (in my case I am moving another, simple single line label, cell below it) my cell changes its height to the default row height (44 pts), squashing the image in the process. This happens in both cases, when auto layout breaks my constraints or when I reduce the priority of height to 999. I'm really at a loss as to how to get these cells to do what I want.
You should try setting the estimatedRowHeight property in code, and also, depending on which version of iOS 6 you're using, set the rowHeight property to UITableViewAutomaticDimension,
self.tableView.estimatedRowHeight = 44;
self.tableView.rowHeight = UITableViewAutomaticDimension;
The default rowHeight for nib or storyboard table views, is supposed to be changed to UITableViewAutomaticDimension at some point; I don't know if it has yet in 6.0.1, so that last line may or may not be necessary.
Are you supporting older version of iOS? If that is the case, be sure to uncheck the Relative to margin option for the constraints that are complaining.

Resources