Detected a case where constraints ambiguously suggest a height of zero

76,459

Solution 1

Three things have managed to silence this warning so far. You can pick up the most convenient for you. Nothing pretty though.

  • To set up default cell's height in viewDidLoad

    self.tableView.rowHeight = 44;
    
  • Go to storyboard and change row height on your tableview to something different than 44.

  • To implement tableview's delegate method heightForRowAtIndexPath

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return 44;
    }
    

Weird.

Solution 2

You're encountering the side effect of a fantastic new feature in iOS8's Tableviews: Automatic Row Heights.

In iOS 7, you either had rows of a fixed size (set with tableView.rowHeight), or you'd write code to calculate the height of your cells and you'd return that in tableView:heightForRowAtIndexPath. Writing code for the calculation of a cell's height could be quite complex if you had numerous views in your cell and you had different heights to consider at different font sizes. Add in Dynamic Type and the process was a pain in the ass.

In iOS 8, you can still do the above, but now the height of the rows can be determined by iOS, provided that you've configured the content of your cell using Auto Layout. This is huge benefit for developers, because as the dynamic font size changes, or the user modifies the text size using Accessibility Settings, your UI can be adaptive to the new size. It also means if you have a UILabel that can have multiple rows of text, your cell can now grow to accommodate those when the cells needs to, and shrink when it does not, so there isn't any unnecessary whitespace.

The warning message you're seeing is telling you that there aren't enough constraints in your cell for Auto Layout to inform the tableview of the height of the cell.

To use dynamic cell height, which, along with the techniques already mentioned by other posters, will also get rid of this message, you need to ensure your cell has sufficient constraints to bind the UI items to the top and bottom of the cell. If you've used Auto Layout before, you are probably accustomed to setting Top + Leading constraints, but dynamic row height also requires bottom constraints.

The layout pass works like this, which occurs immediately before a cell is displayed on screen, in a just-in-time manner:

  1. Dimensions for content with intrinsic sizes is calculated. This includes UILabels and UIImageViews, where their dimensions are based on the text or UIImages they contain, respectively. Both of these views will consider their width to be a known (because you've set constraints for trailing/leading edges, or you set explicit widths, or you used horizontal constraints that eventually reveal a width from side to side). Let's say a label has a paragraph of text ("number of lines" is set to 0 so it'll auto-wrap), it can only be 310 points across, so it's determined to be 120pt high at the current font size.

  2. The UI is laid out according to your positioning constraints. There is a constraint at the bottom of the label that connects to the bottom margin of the cell. Since the label has grown to be 120 points tall, and since it's bound to the bottom of the cell by the constraint, it must push the cell "down" (increasing the height of the cell) to satisfy the constraint that says "bottom of the label is always standard distance from the bottom of the cell.

The error message you reported occurs if that bottom constraint is missing, in which case there is nothing to "push" the bottom of the cell away from the top of the cell, which is the ambiguity that's reported: with nothing to push the bottom from the top, the cell collapses. But Auto Layout detects that, too, and falls back to using the standard row height.

For what it's worth, and mostly to have a rounded answer, if you do implement iOS 8's Auto Layout-based dynamic row heights, you should implement tableView:estimatedHeightForRowAtIndexPath:. That estimate method can use rough values for your cells, and it'll be called when the table view is initially loaded. It helps UIKit draw things like the scrollbar, which can't be drawn unless the tableview knows how much content it can scroll through, but does't need totally accurate sizes, since it's just a scrollbar. This lets the calculation of the actual row height be deferred until the moment the cell is needed, which is less computationally intensive and lets your UITableView be presented quicker.

Solution 3

To resolve this without a programmatic method, adjust the row height of the table view in the Size Inspector from the storyboard.

enter image description here

Solution 4

I had this problem after creating a custom UITableViewCell and adding my subviews to the cell instead of its contentView.

Solution 5

This is an autolayout issue. Make sure that your subviews have all the constraints. For me, the bottom constraint was missing for the Title Label in the cell. When I added that, the warning went away and everything showed up perfectly.

Share:
76,459
David E
Author by

David E

Updated on September 11, 2020

Comments

  • David E
    David E over 3 years

    After updating to Xcode 6.1 beta 2 when I run my app that contains tableview cells, the debug assistant says:

    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.
    

    Before, when I used Xcode 5 on this project, I would get a few errors but those have gone away since I upgraded. I have no other errors or warnings now. I have already tried adjusting the sizes of all the tableview cells and also tried using standard height but I still get the same 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.
    

    I have also read through all similar topics on this but none of their solutions help. When I test the app with the simulator, the app runs fine except the pictures that are supposed to be in the tableView cells aren't there.

  • David E
    David E over 9 years
    So I have tried using your method using the line you gave me but I still come up with the same error. I have also not been using rotation in my app.
  • David E
    David E over 9 years
    I have also tried using your method but I need to add a @property for rowHeight but I do not know the correct object type to use
  • Viktor Kucera
    Viktor Kucera over 9 years
    I might didn't get your note but rowHeight is a property of UITableView. Just connect your table to some outlet and that's it.
  • Guillaume Algis
    Guillaume Algis over 9 years
    This is because if you keep the 44pt value in IB, it will consider you want to use self sizing cells. stackoverflow.com/questions/25888126/… (but, yes, this is a weird behavior indeed)
  • David E
    David E over 9 years
    So apparently I had two viewDidLoad methods and I put the self.tableView.rowHeight = 44; in the wrong one. The error went away! thanks
  • Viktor Kucera
    Viktor Kucera over 9 years
    Thanks Guillaume Algis for making this more clear. It's still very creepy though.
  • Golden Thumb
    Golden Thumb over 9 years
    This is a great explanation of the root reason of this warning. Thx a lot for your time, Woodster!
  • Golden Thumb
    Golden Thumb over 9 years
    Like what Woodster said, I did miss the .Bottom part of constraints. When added my problem got solved.
  • Julio Rodrigues
    Julio Rodrigues over 9 years
    After trying almost 20 things, this is the only one that worked!
  • caribbean
    caribbean over 9 years
    This man nailed it! He deserves and upvote and this must be the accepted answer. +1
  • tdios
    tdios over 9 years
    Nice. this explanation helped out particularly well in my case where I was missing the end "|" when writing auto-layout in code. [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[headlineLabel(>=24)]|" options: 0 metrics:nil views:views]];
  • Sean Tan
    Sean Tan over 9 years
    This answer nailed it. Added the bottom constraint solved the issue. If you are using dynamic height for the table cell, you should not be hardcoding the rowHeight or anything of that matter which is mentioned in Viktor's answer.
  • Zack Shapiro
    Zack Shapiro about 9 years
    This was really helpful. I had multiple UILabels, all associated with one another. I was missing a bottom constraint on the bottom-most one. Adding that enabled the heights to work
  • Josh Valdivieso
    Josh Valdivieso about 9 years
    Thank you, my fault was due to not including a bottom constraint.
  • jonprasetyo
    jonprasetyo almost 9 years
    Just looking at the up votes and as soon as you said bottom constraints is missing - I stopped reading your answer and went back to add it and it works! Thanks
  • hhanesand
    hhanesand almost 9 years
    Don't know why this was downvoted, as it's a perfectly good answer. See here for help on figuring out which cell is having problems being laid out stackoverflow.com/a/29565073/4080860
  • hhanesand
    hhanesand almost 9 years
    See this answer stackoverflow.com/a/29565073/4080860 in order to figure out what cell is missing constraints.
  • Rick van der Linde
    Rick van der Linde almost 8 years
    Durrr, forgot a bottom constraint, thnx.
  • zyc
    zyc almost 6 years
    Best solution for me because is using the storyboard stuffs instead of lines fo code.
  • turingtested
    turingtested over 5 years
    Actually, the warning went away when I disabled self-sizig tableview cells.
  • Jack
    Jack over 5 years
    @turingtested you should enable self sizing tableview cell for giving support on various devices.
  • turingtested
    turingtested over 5 years
    Agree, but please read the original question. What I meant was that your suggested solution didn't work, at least not for me.
  • dinesharjani
    dinesharjani over 5 years
    Always add subviews to the contentView, not to the UITableViewCell directly.
  • Dani
    Dani over 5 years
    Why are you choosing specifically 44?
  • atineoSE
    atineoSE about 5 years
    FYI UITableViewAutomaticDimension has been renamed to UITableView.automaticDimension
  • NRitH
    NRitH about 5 years
    I found the opposite to be more effective: set an explicit estimated height, and let the row height itself be automatic.
  • TruMan1
    TruMan1 almost 5 years
    The real problem is a missing constraint somewhere. You're probably entering something vertically instead of setting top/bottom constraints
  • Brian Green
    Brian Green over 3 years
    This worked for me. Instead of using .defaultLow, i needed to use .defaultHigh