53

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?

Zaporozhchenko Oleksandr
  • 4,660
  • 3
  • 26
  • 48
  • I get them a lot of times on iOS8, I still didn't understand if it could be a sort of iOS8 bug, because in earlier version the exception is not raised. – Andrea Feb 09 '15 at 13:04
  • tried to change to ios 7.0, but it still there – Zaporozhchenko Oleksandr Feb 09 '15 at 13:11
  • Probably is that since a webview is a scrollview is collapsed to 0 height and when the celle is displayed autolayout can't satisfy the top and the bottom constraints. Try to put a fixed height in your webview and see if the warning is still displayed – Andrea Feb 09 '15 at 13:14
  • I can't do that, coz i want (!) for different cells different height, coz of webviewheight. I tried to add webView height constraint >= 5, but it doesn't help – Zaporozhchenko Oleksandr Feb 09 '15 at 13:32
  • I'm having a very similar issue with my table view. I can't get it to resize the cells correctly because an incorrect "UIView-Encapsulated-Layout-Height" value is taking priority and causing conflicting constraints because the content view of the cell (as I made it in IB storyboard--with constraints) is larger than the "UIView-Encapsulated-Layout-Height". I even followed the concepts in this great tutorial: http://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift but still can't get it to work! :( – Ethan G Mar 28 '15 at 06:07
  • 6
    I just want the "UIView-Encapsulated-Layout-Height" to set itself to the height of the cell's content view (since I'm making the content view myself in IB storyboard with constraints). I thought setting tableView.rowHeight = UITableViewAutomaticDimension and setting tableView.estimatedRowHeight to some value would work (as it did in the Ray Wenderlich tutorial), but I can't get it!! – Ethan G Mar 28 '15 at 06:10
  • I'm running into the same issue, Ethan. Did you ever find the solution? – John Stewart Aug 13 '15 at 19:54
  • 2
    Possible duplicate of [what is NSLayoutConstraint "UIView-Encapsulated-Layout-Height" and how should I go about forcing it to recalculate cleanly](https://stackoverflow.com/questions/25059443/what-is-nslayoutconstraint-uiview-encapsulated-layout-height-and-how-should-i) – Ortwin Gentz Sep 21 '17 at 17:32

11 Answers11

92

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.

Fran Sevillano
  • 8,103
  • 4
  • 31
  • 45
  • 7
    It works but what is the real causing under the hood? – Phineas Lue Sep 28 '15 at 23:57
  • @PhineasLue in my case I am having constraint(a) as default constraint then I update and add another constraint(b) where somehow hit the constraint `a` now you need choose between `a` or `b` to be the final constraint that will appear in your view, if you choose `a` you need to set the priority of `b` to 999 its like saying give way to constraint `a` – CaffeineShots Nov 26 '15 at 08:40
  • Thanks for this! Silly that it's necessary, but I'm stoked to get rid of the bogus warning. – flatpickles Jan 09 '16 at 03:01
  • 2
    It works. the results is showing the warning `Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.` have you guys meet this situation? – hzwzw Feb 13 '16 at 01:57
  • This solution worked for me with Xcode Version 7.3.1 (7D1014). What I noticed is that in IB in my case, a UITableViewCell height of 131 px makes the IB auto layout engine happy, but the contentView shows as 130 px in IB which is not correct and not changeable. I think this is a bug between Xcode IB auto layout engine and iOS runtime auto layout. – Neil Jul 31 '16 at 17:21
  • Getting same kind of error for a UIView for which I have set top, trailing, bottom and width constraint. When orientation changed I am modifying the top constraint constant at that time console showing same warning. Once I set priority for the top constraint to 999 , Warning goes aways. Thanks for answer it helped me a lot :). I have question but why height constraint added by the OS? – The iCoder Jul 27 '17 at 13:12
  • I've applied it to a subview with fixed height on dynamic-height parent view, and it worked perfectly. It's kind of make sense. – DragonCherry Jan 03 '20 at 07:37
  • But how? where do I add it? what is the name of the constraint? – אורי orihpt Oct 31 '20 at 19:53
17

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

Paul T.
  • 4,938
  • 7
  • 45
  • 93
  • 2
    Heads up to anyone else reading this. There are also .estimatedSectionHeaderHeight and .estimatedSectionFooterHeight attributes as well if you are using headers and or footers. – Trevis Thomas Aug 14 '17 at 17:38
  • 1
    FYI - I've seen differences in setting the estimated row height on the table view vs. implementing the function. The function works, the setter doesn't seem to in my case. – Mike Sep 11 '17 at 20:54
5

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.

superarts.org
  • 7,009
  • 1
  • 58
  • 44
4

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.

John Stephen
  • 7,625
  • 2
  • 31
  • 45
3

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

夜一林风
  • 1,247
  • 1
  • 13
  • 24
  • 1
    Yes I had the same issue. Remove any setNeedsLayout and layOutIfNeeded calls when cell is being reused. – Ankit J Oct 30 '18 at 12:15
3

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.

perec
  • 51
  • 4
2

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.
ngobw
  • 406
  • 4
  • 4
2

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.

DevAndArtist
  • 4,971
  • 1
  • 23
  • 48
1

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.

Rivera
  • 10,792
  • 3
  • 58
  • 102
0

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:.

Mike
  • 9,765
  • 5
  • 34
  • 59
0

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

Leonid Silver
  • 384
  • 4
  • 8