How is it possible that UITableViewCellContentView height is different from heightForRowAtIndexPath:

15,468

Solution 1

I found the answer here : Auto layout constraints issue on iOS7 in UITableViewCell

We just have to set the AutoresizingMask of the contentView to UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth and ... problem solved!

Solution 2

You could try to set the (/some) heights at a lower priority (e.g. @900). I had a similar issue (my UITableViewCellContentView was too small and the constraints could not be satisfied). After I lowered the priority of my "wrong" height it was laying out nicely at the intended heights.

Solution 3

You have to turn off autoresizing conversion for the view that contains your constraints if you add your constraints with code or visual language:

    [self.someView setTranslatesAutoresizingMaskIntoConstraints:NO];

This prevents the [UITableViewCellContentView:0x1ef2bf50(147)] constraint from being created.

Solution 4

In cellForRowAtIndexPath you request a cell from the tableview. The cell you get will either be a newly created cell (with size 320,44) or a cell that has been dequeued and sent the prepareForReuse message (with whatever size it had previously). When you apply code NSLayoutConstraints to the contentView they are resolved before the cell fits itself to the tableview space provided. This makes no sense but is definitely the conclusion of my observations.

So, in my instance I was getting new cells with 44 height but one of my constraints was for a fixed height of 48. This was throwing exceptions constantly and making debugging a pain. All I did to make the exceptions go away was to set the frame of the cell to the correct height (and width I suppose if you are experiencing issues on the horizontal dimension) when I was preparing it in cellForRowAtIndexPath.

UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil)
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// If the cell is new its frame will be (0,0,320,44)
cell.frame = CGRectMake(0,0,tableview.frame.size.width,calculatedHeightRequiredForLayout);
[cell.contentView addConstraints:constraints];

The cell will automatically resize itself to the correct dimensions before it displays in the tableview so you won't cause any issues, but your layout constraints will be applied without 'needing to be broken' by iOS...

Share:
15,468
Talal MAZROUI
Author by

Talal MAZROUI

CTO and co-founder of TvShow Time

Updated on June 13, 2022

Comments

  • Talal MAZROUI
    Talal MAZROUI almost 2 years

    I'm facing a really weird problem on my UITableView. I have some different cells that I want to display on a newsfeed-like table view.

    And I have a problem with a cell after reuse. The cell contains two images, two labels and a view with the share/like/comment buttons. I'm gonna try to draw it, but I'm not sure it's gonna be pretty :

    -------------------------------------------------
    |       |   __    ____________________________  |
    |       |  |_2|  |                            | |
    |       |        |              3             | |
    |       |        |                            | |
    |   1   |        |____________________________| |
    |       |                                       |
    |       |_______________________________________|
    |       |                                       |
    |       |                  4                    |
    |_______|_______________________________________|
    |                                               |
    |                       5                       |
    |_______________________________________________|
    
    1 : objectImage
    2 : subjectImage
    3 : titleLabel
    4 : commentLabel
    5 : actionsView
    

    And my constraints are :

    "H:|-0-[objectImage(60)]-7-[subjectImage(30)]-7-[titleLabel]-7-|"
    "H:|-0-[objectImage(60)]-0-[commentLabel]-0-|"
    "H:|-0-[actionsView]-0-|"
    "V:|-0-[objectImage(>=35)]-0-[actionsView(44)]-0-|"
    "V:|-7-[subjectImage(30)]"
    "V:|-7-[titleLabel(>=46)]-7-[commentLabel(>=35)]-0-[actionsView(44)]-0-|"
    

    And every time the cell is drawn, I change this constraint:

    "V:[commentLabel(%0.2f)]"
    

    The cells display perfectly the first time.

    But, the problem I have is that at a point, after some reuse (I can't reproduce it every time) the app crashes because of a constraint problem. Here is the exception:

    "<NSLayoutConstraint:0x205a75b0 V:[UILabel:0x1ef31430(105)]>",
    "<NSLayoutConstraint:0x1ef34440 V:[UILabel:0x1ef31430]-(0)-[UIView:0x1ef2fe50]>",
    "<NSLayoutConstraint:0x1ef34380 V:[UILabel:0x1ef31250]-(7)-[UILabel:0x1ef31430]>",
    "<NSLayoutConstraint:0x1ef33900 V:|-(7)-[UILabel:0x1ef31250]   (Names: '|':UITableViewCellContentView:0x1ef2bf50 )>",
    "<NSLayoutConstraint:0x1ef34340 V:[UILabel:0x1ef31250(>=46)]>",
    "<NSLayoutConstraint:0x1ef33210 V:[UIView:0x1ef2fe50]-(0)-|   (Names: '|':UITableViewCellContentView:0x1ef2bf50 )>",
    "<NSLayoutConstraint:0x1ef331d0 V:[UIView:0x1ef2fe50(44)]>",
    "<NSAutoresizingMaskLayoutConstraint:0x1ef36f90 h=--& v=--& V:[UITableViewCellContentView:0x1ef2bf50(147)]>"
    
    
    Will attempt to recover by breaking constraint 
    <NSLayoutConstraint:0x1ef34380 V:[UILabel:0x1ef31250]-(7)-[UILabel:0x1ef31430]>
    

    The problem is that the constraint [UITableViewCellContentView:0x1ef2bf50(147)] is not right.

    What is weird is that the heightForRowAtIndexPath: returns the correct value which is 217.

    And what I don't understand is that the height of the UITableViewCell is correct!

    (lldb) po 0x1ef2bf50
    $0 = 519225168 <UITableViewCellContentView: 0x1ef2bf50; frame = (0 0; 320 147); gestureRecognizers = <NSArray: 0x1ef30a20>; layer = <CALayer: 0x1ef2a3d0>>
    (lldb) po [0x1ef2bf50 superview]
    $1 = 0x1ef30e40 <NewsSubjectCommentCell: 0x1ef30e40; baseClass = UITableViewCell; frame = (0 1055; 320 217); hidden = YES; autoresize = W; layer = <CALayer: 0x1ef25e10>>
    

    So I don't understand how is it possible that the height constraint of UITableViewCellContentView is 147. It is the height of another cell of the same type, but it should be changed to 209, right?

    So, if you have any insight on how this can happen (maybe I did something wrong), I'd be glad.

    Thanks,

  • Talal MAZROUI
    Talal MAZROUI about 11 years
    The view that contains my constraints is my custom UITableViewCell. I already tried what you are suggesting, but when I do so, I have the error "Assertion failure in -[NewsSubjectCommentCell layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2380.17/UIView.m:5776". BTW, if anyone could tell me how to get the assertion message (so that I know where to look exactly to debug), I'd love it. I've been searching for months ...
  • Whakkee
    Whakkee about 11 years
    Try calling this method on the superview of your UITableViewCell. Maybe it's better to ask about the assertion failure / message in a separate question, to keep this clean.
  • Erik W
    Erik W almost 11 years
    You can't. You have to do this swizzle to disable turning autoresizing mask into constraints on a table view cell: stackoverflow.com/a/12941256/180445 This will fix the assertion failure. This was my ultimate solution to the OP.
  • ninjudd
    ninjudd about 10 years
    I was getting "Unable to simultaneously satisfy constraints" warnings when attempting to follow the instructions here: stackoverflow.com/a/18746930/528620. Setting [self.contentView setAutoresizingMask:UIViewAutoresizingFlexibleHeight] fixed it. Thanks!
  • giampaolo
    giampaolo over 9 years
    This worked for me. Changing bounds, or setting UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleW‌​idth did not.
  • John Rogers
    John Rogers over 8 years
    This also worked for me. I added a height constraint and set it to 900 and voila.
  • lm2s
    lm2s over 8 years
    Thank you! You're a savior. I was going nuts with the "Unable to simultaneously satisfy constraints".
  • Alper
    Alper over 5 years
    This was it for me. Somehow there's another constraint being added at the same priority by the UITableViewCell?