21

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
  • 645
  • 1
  • 6
  • 12
  • Have you found a solution? I'm having the exact same issue. – Erik W Jun 18 '13 at 22:40
  • No, the (bad) solution I used was to add 1 to the cell height in the heightForRowAtIndexPath: function – Talal MAZROUI Jun 25 '13 at 14:05
  • http://stackoverflow.com/questions/12610783/auto-layout-still-required-after-executing-layoutsubviews-with-uitableviewcel/39136021#39136021 – Alfy Aug 25 '16 at 07:04

5 Answers5

16

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!

Community
  • 1
  • 1
Talal MAZROUI
  • 645
  • 1
  • 6
  • 12
  • 3
    I was getting "Unable to simultaneously satisfy constraints" warnings when attempting to follow the instructions here: http://stackoverflow.com/a/18746930/528620. Setting `[self.contentView setAutoresizingMask:UIViewAutoresizingFlexibleHeight]` fixed it. Thanks! – ninjudd Apr 24 '14 at 23:19
  • Thank you! You're a savior. I was going nuts with the "Unable to simultaneously satisfy constraints". – lm2s Nov 26 '15 at 17:30
12

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.

  • 2
    This worked for me. Changing bounds, or setting UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth did not. – giampaolo Aug 20 '14 at 16:15
  • This also worked for me. I added a height constraint and set it to 900 and voila. – John Rogers Nov 24 '15 at 01:05
  • This was it for me. Somehow there's another constraint being added at the same priority by the UITableViewCell? – Alper Sep 26 '18 at 11:09
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.

Whakkee
  • 1,867
  • 1
  • 16
  • 18
  • 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 ... – Talal MAZROUI Apr 16 '13 at 17:39
  • 1
    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. – Whakkee Apr 16 '13 at 17:42
  • You can't. You have to do this swizzle to disable turning autoresizing mask into constraints on a table view cell: http://stackoverflow.com/a/12941256/180445 This will fix the assertion failure. This was my ultimate solution to the OP. – Erik W Jun 25 '13 at 19:39
1

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

Red Nightingale
  • 669
  • 3
  • 19
0

I once struggled with something similar. Tried bazzilion of solutions. Nothing worked. And at the and I noticed that accidentally I created a cell in designer as UICollectionViewCell instead of UITableViewCell.
Just in case anyone would ever fill the same pain, check that too

mykolaj
  • 974
  • 8
  • 17