Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoLayout breaks constraints when layoutIfNeeded() is called

I'm trying to implement a dynamic height UITaleViewCell in UITableView with XCode6 using Swift.

I laid out my cell as following, by setting up the constraints graphically(Screenshot is from XCode5, because of NDA on XCode6). I also set the BodyLabel's Line Break property to 'Word Wrap', and set the Line number to '0' to allow multiple lines.

enter image description here

Now if I just set up the cell's contents inside tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) method, then I get the dynamic height behavior correctly.

However, since I was following along tutorials available online(specifically this one), I added another method to determine the height of the cell with tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!). In the tutorial that I was following, it told me to add cell.layoutIfNeeded(), so I added that too.

override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {      var cell = tableView!.dequeueReusableCellWithIdentifier(kCellIdentifier) as GroupFeedCell      // Configure the cell     if let frc = self.fetchedResultsController {         let feed = frc.objectAtIndexPath(indexPath) as GroupFeed         cell.titleLabel.text = feed.name         if let message = feed.message {             cell.bodyLabel.text = message         }     }      // Layout the cell     cell.layoutIfNeeded()      // Get the height     var height : CGFloat = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height     return height } 

However, when I ran the program, although the table view still displayed the dynamic heights of the cells correctly, it displayed the errors like this:

2014-07-27 13:59:22.599 FBGroups[4631:979424] 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 and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer    to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)  (     "<NSLayoutConstraint:0x17809e780 H:[UILabel:0x14fd12f50'Body Label Contents...']-(8)-|   (Names:    '|':UITableViewCellContentView:0x178185d70 )>",     "<NSLayoutConstraint:0x17809e7d0 H:|-(8)-[UILabel:0x14fd12f50'Body Label Contents...']   (Names:    '|':UITableViewCellContentView:0x178185d70 )>",     "<NSLayoutConstraint:0x17809ea50 'UIView-Encapsulated-Layout-Width' H:[UITableViewCellContentView:0x178185d70(0)]>" )  Will attempt to recover by breaking constraint  <NSLayoutConstraint:0x17809e780 H:[UILabel:0x14fd12f50'Body Label Contents...']-(8)-|   (Names:     '|':UITableViewCellContentView:0x178185d70 )>  Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.   

I tried to figure out what might have gone wrong, and spend good amount of time on it, and I figured out that whenever I delete cell.layoutIfNeeded() method, then the constraints error disappears.

And it seemed that among the constraints that are conflicting, UIView-Encapsulated-Layout-Width was not the one I added, and other than that, the all of the constraints looked innocent to me. I tried to search through what could generate UIView-Encapsulated-Layout-Width constraints, but I couldn't get the satisfying explanation in my situation. I would like to know what would be the cause of this error message and how to resolve this problem.

Also, can someone explain what would be the purpose of calling cell.layoutIfNeeded() method inside calculating height of the cell, and when it would be necessary? Most of the tutorials that were covering dynamic height UITableViewCell utilized this method, although my program still displayed cells correctly without that method call, and whenever I tried to use that method, it caused the exceptions.

like image 600
YShin Avatar asked Jul 27 '14 19:07

YShin


People also ask

What Does layoutIfNeeded do?

layoutIfNeeded()Lays out the subviews immediately, if layout updates are pending.

Why Autolayout?

Auto Layout is the preferred technology to define layouts for user interfaces on iOS and macOS. Its goal: To make it easy for you to create user interfaces that adapt automatically to different screen sizes and orientations. With Auto Layout enabled, you cannot set a view's frame manually.


1 Answers

In Xcode, set the priority of the very bottom vertical constraint to 750 (or anything less than a 1000).

like image 147
Tarek Avatar answered Sep 18 '22 14:09

Tarek