Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS8 self-sizing static TableView cells with Interface Builder

I am excited by the prospect of being able to build my static TableViews right within Xcode, using Auto Layout to support dynamic type, as mentioned in WWDC2014 What's New in Table and Collection Views.

I'd prefer to use strictly Xcode / Interface Builder and storyboards to handle the Auto Layout. When I do, somehow the TableView cells are not resizing and I'm sure I'm missing something simple.

To reproduce this, using Xcode 7 beta 5, I:

  • Created a new single view project.
  • Set the Storyboard entry point to a new UITableViewController.
  • Make it a static table view with grouped style.
  • Added a single label to the first row. Added constraints to the top, bottom, left, and right.
  • Set the label font to be "Body".
  • Added to ViewDidLoad:

    self.tableView.rowHeight = UITableViewAutomaticDimension; self.tableView.estimatedRowHeight = 44.0;

  • Ran it and adjusted Dynamic Type in Settings. While the font changes, the TableView height remains stuck at the apparent default of 44 and truncates the label.

Truncated label in Simulator

Here is a GitHub repository which is the result of the above.

Why isn't Auto Layout causing the TableView to expand to fill the necessary space to fit the new larger label text?

I have found great posts on the subject such as the following, with a bent on using code to set up constraints here.

I'm not finding any examples of doing this in pure Interface Builder. Surely this is quite possible?

Update

I have updated the GitHub source to include a second table row with an ImageView instead of a UILabel; it shows the same issue:

Updated screenshot

Additionally, when I set an explicit height constraint on either the label or image view, I generate the following. The problem seems to be this "UIView-Encapsulated-Layout-Height" constraint which I have not set. I'm guessing it's generated because in my static tableview in IB, the Row Height is set (as default) to 44.

Unable to simultaneously satisfy constraints.
...

"<NSLayoutConstraint:0x7fa371f39e30 V:[UILabel:0x7fa371f38d30'Label'(20)]>",
"<NSLayoutConstraint:0x7fa371c39160 UILabel:0x7fa371f38d30'Label'.top == UITableViewCellContentView:0x7fa371e17dc0.topMargin>",
"<NSLayoutConstraint:0x7fa371c393c0 UITableViewCellContentView:0x7fa371e17dc0.bottomMargin == UILabel:0x7fa371f38d30'Label'.bottom>",
"<NSLayoutConstraint:0x7fa371f41a40 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7fa371e17dc0(43.5)]>"

But shouldn't this in ViewDidLoad be overriding this?

self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0;

Do self-sizing table view cells simply not work with static table views?

Update 2

I have built the same thing using a dynamic prototype instead of a static table view, and all works fine:

enter image description here

It does indeed seem to be static versus dynamic prototyped tables. Static table view cells do not properly expand.

I've seen no mention of dynamic vs. static in the WWDC videos, so at this point I'm chalking this up to a bug. Will update if I learn anything new.

I have updated the GitHub repository above to show an example of both the static (broken) and dynamic (working) table views.

like image 823
John Stewart Avatar asked Aug 13 '15 05:08

John Stewart


2 Answers

Answer:

This is a bug in Xcode7b5. I have just confirmed this by following the identical steps in Xcode 6.4 and Xcode 7b5.

  1. Create new Single View Application
  2. New File. Cocoa Class "MyStaticTableViewController", subclass of UITableViewController.
  3. In Storyboard, drag in new Table View Controller.
  4. Change Class to MyStaticTableViewController.
  5. Drag storyboard entry point to new VC.
  6. Delete original VC.
  7. Change Class to MyStaticTableViewController for new VC.
  8. Select the Table View. Change Content to Static Cells and Style to Grouped.
  9. Drag new label to first Table View Cell. Change Font to Body. Set top, bottom, left, right constraints to 0 and update frames.
  10. In MyStaticTableViewController.m, add:
 - (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.rowHeight = UITableViewAutomaticDimension;
    self.tableView.estimatedRowHeight = 44.0;

}
  1. Verify with Dynamic Type that increasing the size causes the table row to expand as well.

The project created by Xcode 6.4 works as expected - the table view cells expand to fit the label.

The project created by Xcode 7b5 fails as described in the original question.

Interestingly, if open the Xcode6 project with Xcode7, it works fine as well. It's something to do with how Xcode7 is creating the project, or storyboard.

Update

I compared the .storyboard files to each other, and in the broken Xcode7b5 one under the tableView entry, there is a rect defined:

<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>

I deleted this line and it seems that the table view cell now properly self-sizes!

Update 2

The key issue seems to be a "rect" entry left under each of the "tableViewCell" entries in the XML file. Whacking those is what fixes this issue.

Update 3

Filed radar:

"Engineering has determined that your bug report (22311571) is a duplicate of another issue (17995201) and will be closed."

like image 135
John Stewart Avatar answered Nov 09 '22 01:11

John Stewart


I haven't got time to look at the code, but I'm almost sure the problem is the label. The font size changes but the size of the label doesn't. I'm suspecting that because the text is not being truncated after occupying the whole row, it's leaving a small margin.

Do a quick test: put a colored background to the text label. My bet is that you'll notice it's not growing. If it doesn't, take a look here: Adjust UILabel height depending on the text

like image 20
Bartserk Avatar answered Nov 09 '22 03:11

Bartserk