My layout constraints are fine in Interface Builder but an exception occurs at runtime thanks to some part of the framework applying fixed height and width constraints that I really don't want. Why are they there, and how to turn them off?
They're the last two constraints shown in the logged list:
2014-04-26 09:02:58.687 BBCNews[32058:60b] 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:0xbf478a0 UIView:0xbf4a3c0.height == 0.28125*UIView:0xbf4a3c0.width>",
"<NSLayoutConstraint:0xbf47190 UIView:0xbf4a3c0.leading == BNMyNewsCell_landscape:0xbf48b10.leading>",
"<NSLayoutConstraint:0xbf47160 UIView:0xbf4a3c0.trailing == BNMyNewsCell_landscape:0xbf48b10.trailing>",
"<NSLayoutConstraint:0xbf47130 BNMyNewsCell_landscape:0xbf48b10.bottom == UIView:0xbf4a3c0.bottom>",
"<NSLayoutConstraint:0xbf47100 UIView:0xbf4a3c0.top == BNMyNewsCell_landscape:0xbf48b10.top>",
"<NSLayoutConstraint:0xd4c3c40 'UIView-Encapsulated-Layout-Width' H:[BNMyNewsCell_landscape:0xbf48b10(304)]>",
"<NSLayoutConstraint:0xd4c38a0 'UIView-Encapsulated-Layout-Height' V:[BNMyNewsCell_landscape:0xbf48b10(290)]>"
}
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0xbf478a0 UIView:0xbf4a3c0.height == 0.28125*UIView:0xbf4a3c0.width>
If you see the error message contains UIView-Encapsulated-Layout-Width , which means your constraints relative to width conflict with it. For example, you set label constrains: [ leading , trailing , bottom , top ] or [ CenterX , leading , bottom , top ] leading trailing and CenterX are for width.
The relationship between two user interface objects that must be satisfied by the constraint-based layout system.
translatesAutoresizingMaskIntoConstraints. A Boolean value that determines whether the view's autoresizing mask is translated into Auto Layout constraints.
This may not answer your question, but it could help others like me who got here from search.
I was getting a strange AutoLayout broken constraint error accompanied by a UIView-Encapsulated-Layout-Width
constraint because I was adding a tableHeaderView
to a table view that hadn't been sized with AutoLayout yet. So the system was trying to apply my header subviews' constraints inside a tableview with a frame of {0,0,0,0}
. Since UITableView likes control over the width of its elements, its generated width constraint, UIView-Encapsulated-Layout-Width
, was set to zero, causing all kinds of confusion with my header elements that were expecting 320+pt width.
The takeaway: make sure you are adding/manipulating your supplementary/header/footer views after the tableview has been sized by AutoLayout.
Based on a ton of observation I believe (but cannot know for certain) that the constraints named UIView-Encapsulated-Layout-Width
and UIView-Encapsulated-Layout-Height
are created by UICollectionView
and friends, and exist to enforce the size returned by the sizeForItemAtIndexPath
delegate method. I guess it's there to ensure that the UICollectionViewCell
set up by cellForItemAtIndexPath
ends up the size that it was told it would be.
Which answers my initial question here. A second question is why were the constraints unsatisfiable? The cell's intrinsic height should have been the same as UIView-Encapsulated-Layout-Height
. Again, I don't know for certain, but I suspect it was a rounding error (i.e. intrinsic height came to 200.1 pixels, the UIView-Encapsulated-Layout-Height
maybe rounded to 200. The fix I came up with was to just lower the priority of the relevant cell constraint to allow UIView-Encapsulated-Layout-Height
to have the last word.
I was facing the same weird constraint and had no idea why, until I remembered the darned translatesAutoresizingMaskIntoConstraints
property. Setting this to false
solved the problem.
What happens in the background is that the auto resizing masks (the old layout engine for iOS) are converted to constraints. Very often you don't want these constraints and want your own ones. In such cases you should set this property to false and you'll be fine:
view.translatesAutoresizingMaskIntoConstraints = false
Definitely seeing this on a UITableView
's tableHeaderView
. I was able to get this to work with a custom header view by explicitly setting the width equal to that of the tableView
after setting the tableHeaderView
, THEN resetting it after a layout pass has completed.
Example code for iOS 9, which assumes you have a UITableView
passed into your method as tableView
and an item to configure it as item
:
//Create the header view
self.contentDetailHeaderView = MyCustomHeaderView()
//Turn on autolayout
self.contentDetailHeaderView.translatesAutoresizingMaskIntoConstraints = false
//Add the header to the table view
tableView.tableHeaderView = self.contentDetailHeaderView
//Pin the width
let widthConstraint = NSLayoutConstraint(item: self.contentDetailHeaderView,
attribute: .Width,
relatedBy: .Equal,
toItem: tableView,
attribute: .Width,
multiplier: 1,
constant: 0)
tableView.addConstraint(widthConstraint)
//Do whatever configuration you need to - this is just a convenience method I wrote on my header view.
self.contentDetailHeaderView.setupForItem(item)
//Lay out the configured view
self.contentDetailHeaderView.layoutIfNeeded()
//Reset the table header view, because ¯\_(ツ)_/¯
tableView.tableHeaderView = self.contentDetailHeaderView
Couple of notes, mostly for when I look this up again because I have the memory of a goldfish:
viewDidLayoutSubviews
- I was able to use this technique as long as the tableView
has the appropriate width during setup. .xib
and then making sure all items were pinned so that as the view changed width, the height would then update.viewForHeaderInSection
, you're probably better off grabbing something offscreen which you can lay out a la this technique. I haven't had much luck with the self-sizing bits. 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