Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix strange NSLayoutConstraint errors that don't seem to effect layout in custom UITableViewCell

Each time one of my custom UITableViewCells is drawn by tableView:cellForRowAtIndexPath: The console spits out a bunch of NSLayoutConstraint inconsistencies. I understand most of these:

 Unable to simultaneously satisfy constraints. ...boring stuff..

 "<NSLayoutConstraint:0x8b0eb60 V:|-(NSSpace(20))-[UILabel:0x8b0cb30]   (Names: '|':UITableViewCellContentView:0x8bd7d40 )>",
"<NSLayoutConstraint:0x8b0db70 V:[UILabel:0x8b0cb30]-(NSSpace(8))-[UITextView:0x91dba00]>",
"<NSLayoutConstraint:0x8b0dba0 V:[UITextView:0x91dba00]-(NSSpace(20))-|   (Names: '|':UITableViewCellContentView:0x8bd7d40 )>",
"<NSLayoutConstraint:0x8b0d5a0 V:[UITextView:0x91dba00(1000)]>",
"<NSAutoresizingMaskLayoutConstraint:0x8b00330 h=--& v=--& V:[UITableViewCellContentView:0x8bd7d40(44)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x8b0db70 V:[UILabel:0x8b0cb30]-(NSSpace(8))-[UITextView:0x91dba00]>

Or at least I think I do. What really puzzles me is that my UITableViewCell is working and no constraints seem to be broken. I think some constraints listed in the error, particularly the last one, are constraints added by the system. Is this possible if I don't use .xibs and have only added constraints in code? The last line in the error sticks out to me in particular because I'm dynamically generating the height for each code but I noticed the 44 in there, the default cell height.

Are some of these constraints added by default, say for example when I call [super updateConstraints]? How would I go about resolving these errors or finding out where they are coming from?

On a side note, I understand that dipping into Core Text performs much better than my UITextView + Auto Layout solution. For now I'm working on caching cell heights. However, could these layout errors be causing lag while scrolling or is that simply because I'm using Auto Layout to calculate each cell height as it comes on screen?

I've posted the project in which these errors are occurring on Github if anyone wants to download and experience the weirdness for themselves.

like image 283
Shawn Throop Avatar asked Nov 10 '13 01:11

Shawn Throop


1 Answers

As per Aaron's suggestion I manually change the height of the cell when it is initialized so that the constraints can then reign it in when Auto Layout does its calculations. Without setting the content frame initially, the default frame is {0, 0, 320, 44}. This is too small and cannot satisfy the constraints and errors show up in the console.

Similarly, when reusing cells the old contentView.frame (calculated by Auto Layout) sticks around. This is fine if you're using same amount of text - or less - but if the new cell needs to have more text (and therefore a bigger contentView.frame) we run into the same problem, the contentView.frame is too small and can't satisfy the constraints.

So, in my custom UITableViewCell I now manually set the contentView.frame.height in initWithStyle: and prepareForReuse: to a constant big enough to accommodate any amount of text (enough for an App.net post and some extra headroom). This ensures no errors when Auto Layout does its calculations.

I might even think about setting this value a little higher, or even dynamically, to accommodate for Dynamic Text in iOS 7. As for scrolling, it appears the errors didn't exacerbate the choppy scrolling, thats all because of Auto Layout calculations (I think). Next step is to calculate cell heights when viewDidAppear: is called...

like image 188
Shawn Throop Avatar answered Nov 19 '22 18:11

Shawn Throop