Strange UIView-Encapsulated-Layout-Height Error

IosObjective CUitableviewWebviewConstraints

Ios Problem Overview


I'm making test application, so in my tableviewCell in storyboard I have imageView & webView (webview to show html-text).

I set constraints like top/left/right/height=200 for imageView, spacing=5 between them & left/right/bot for webView, so I want to calculate my webView height programmatically and then change cell's height to stretch my webView. But I got this :

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 & fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property

    translatesAutoresizingMaskIntoConstraints) 
    (
        "<NSLayoutConstraint:0x7fd6f3773f90 V:[UIImageView:0x7fd6f3773e90(200)]>",
        "<NSLayoutConstraint:0x7fd6f3774280 UIImageView:0x7fd6f3773e90.top == UITableViewCellContentView:0x7fd6f3462710.topMargin>",
        "<NSLayoutConstraint:0x7fd6f3774320 V:[UIImageView:0x7fd6f3773e90]-(5)-[UIWebView:0x7fd6f3462800]>",
        "<NSLayoutConstraint:0x7fd6f3774370 UITableViewCellContentView:0x7fd6f3462710.bottomMargin == UIWebView:0x7fd6f3462800.bottom>",
        "<NSLayoutConstraint:0x7fd6f375ee40 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7fd6f3462710(205)]>"
    )

Any suggestions?

Ios Solutions


Solution 1 - Ios

I usually remove this warning by lowering the priority of the constraint that AutoLayout is trying to break. So if it says:

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7fd7c2ecb520 V:[UIView:0x7fd7c2ecd0e0(300)]>

Go ahead and lower that one's priority to 999.

That should work.

Cheers.

Solution 2 - Ios

if you use tableView.rowHeight = UITableViewAutomaticDimension, you should always set estimatedRowHeight. For example:

tableView.estimatedRowHeight = 44

or you should implement:

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat

otherwise you will always get the warning UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView and the content will be collapsed in a wrong way

Solution 3 - Ios

For me I use estimated height for cells, and to solve this problem, I set the priority of the constraint from label bottom to it's neighbor to 999 and it worked.

Solution 4 - Ios

I've seen two cases where this happens so far. One is documented in the accepted answer, which is that your tableView:heightForRow: implementation must return the same value your constraints will compute to.

The other time this happens is if you forget to set translatesAutoresizingMaskIntoConstraints = NO (or false for Swift) on one or more autolayout views. Before adding constraints to a programmatically created view, turn off autoresizing like this:

view.translatesAutoresizingMaskIntoConstraints = false

Otherwise, if your view has a fixed width or height specified by the autoresizing mask then a constraint will be created to enforce it.

Solution 5 - Ios

The following piece of code not worked for me

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }
    
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

Neither add translatesAutoresizingMaskIntoConstraints=false to a bunch of views.

Finally, Removing cell.updateConstraintsIfNeeded() in datasource callback function tableView:cellForRowAt makes Xcode content

Solution 6 - Ios

I ran into this problem today:

  • Xcode 11
  • using UITableViewAutomaticDimension
  • using estimatedRowHeight

One of the factors that fixed the issue was setting the tableView 'Separator' property to 'None' in the storyboard.

Also, if your constraints result in a fractional height (for example if you are using a multiplier based on an aspect ratio) then it will cause a conflict with UIView-Encapsulated-Layout-Height, which is always constrained to integral values. The solution is to lower the priority on your height constraint slightly.

Solution 7 - Ios

Sorry that I'm late to the game. :)

Lowering the priority of the constraint that Autolayout is trying to break might not be the solution if the constraint is required in the first place.

I had this issue the other day, here's what my layout looked like:

  • OuterView <-- C1: A width constraint equal to it's superview
  • StackView <-- C2: A width constraint equal to the OuterView
    • ChildView <-- C3: A fixed width constraint, constant = StackView.frame.size.width

The issue happened when I was reducing the width of C1, so obviously because C3 was on a fixed width that took the original frame size, reducing C1 caused conflicts and C1 was broken by iOS to fix the issue.

Issue was quickly fixed by setting C3 to take StackView's widthAnchor instead of its frame size.

Wrong Constraint

view.widthAnchor.constraint(equalToConstant: stackView.frame.size.width).isActive = true

Right Constraint

view.widthAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 1.0).isActive = true

This way, whenever C1 changes, all child constraints will react to it accordingly.

Conclusion:

  1. I do not think this error was a bug as stated by some.
  2. Resolving by adjusting the priority works, but is that the intended result you wanted?
  3. If you are determined to resolve it without priority, look at your constraints, especially those set programmatically, to check for conflicts. If you are dealing with dynamic width or height for your views such as cell views, make sure the parent view's height or width constraint do not conflict with these dynamic changes and just keep working upwards.

Solution 8 - Ios

I run today into this problem. I had one collection view on the screen but that was not the issue. I was using a custom container view controller and some views were layed-out before the container view itself was layed-out. The trick was to ensure that the container view was layed-out first by calling loadViewIfNeeded() on the container view controller.

That means if 0x7fd6f375ee40 from the original question is the view from a view controller you may need to check if you're loading that view hierarchy before some subviews are layed-out.

Solution 9 - Ios

This error happened to me with a UIButton trying to auto-adjust its height by creating a UIView-Encapsulated-Layout-Height that conflicts with my top and bottom constraints.

I fixed it by explicitly adding a height constraint.

Solution 10 - Ios

I was trying to implement a simple cell with a one line top label and an n line bottom label that would expand with longer text, with the hopes that the cell would automagically expand to fit the content based on my constraints.

Interestingly enough for me, the fix for this was to override - tableView:heightForRowAtIndexPath: and tableView:estimatedHeightForRowAtIndexPath: and return my estimated row height and UITableViewCellAutomaticDimension instead of setting the rowHeight and estimatedRowHeight on my tableView in viewDidLoad:.

Solution 11 - Ios

I had a similar issue with UITextView. Though the question was asked about UIImageView, many people view it when they have other table view layout issues. This answer is applicable in any case, so I decided to share it.

In my case none of the provided answers helped (though they are right ones). So I want to share a dirty hack that solved my issue.

  1. ensure that you have set your tableView.estimatedRowHeight to some value, and tableView.rowHeight = UITableView.automaticDimension
  2. ensure that your cell's subviews have clear layouts that constraint them both horizontally and vertically (horizontal determination is also important).
  3. (HACK HERE) Add a property to your cell var hack: (()-> Void)?. Set it in your cellForRowAtIndexPath as
cell.hack = { [weak self] in
    tableView.beginUpdates()
	tableView.endUpdates()
}

Call this block from the cell when you want it to be resized

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZaporozhchenko OleksandrView Question on Stackoverflow
Solution 1 - IosFran SevillanoView Answer on Stackoverflow
Solution 2 - IosPaul T.View Answer on Stackoverflow
Solution 3 - Iossuperarts.orgView Answer on Stackoverflow
Solution 4 - IosJohn StephenView Answer on Stackoverflow
Solution 5 - Ios夜一林风View Answer on Stackoverflow
Solution 6 - IosperecView Answer on Stackoverflow
Solution 7 - IosngobwView Answer on Stackoverflow
Solution 8 - IosDevAndArtistView Answer on Stackoverflow
Solution 9 - IosRiveraView Answer on Stackoverflow
Solution 10 - IosMikeView Answer on Stackoverflow
Solution 11 - IosLeonid SilverView Answer on Stackoverflow