简体   繁体   中英

Why does modally presenting a view controller break Auto Layout in my table view?

Sample Project: http://cl.ly/1o2K2m2r262q

I have a UITableView with custom cells that have their height auto-calculated from Auto Layout. The custom cells has three labels within it, each positioned with vertical spacing between one another and the content view, and pushed away from the left side.

It works great when I input the data and it loads.

However when I modally present a view controller from the view controller hosting the table view, I notice it completely breaks Auto Layout as I return to the original view controller.

What would cause this? I populate the data into a simple array that acts as the model for the table view's data source, then it's just Auto Layout. It's such a simple project that I'm confused where it would be messing up.

Addition: I appreciate rdelmar's answer, but I simply can't believe that there's not a single app shipped right now that takes advantage of this dynamic cell feature of iOS 8 without making terribly jumpy table views. It would be incredibly noticeable. Someone must have figured out a way to make this work, otherwise they never would have shipped it.

You have several problems. In the storyboard, there is a red warning arrow in the scene list. You shouldn't ignore that. Click on it and make the changes it suggests (do the compression resistance values first, and I think the content hugging one goes away on its own).

In MasterViewController's viewDidLoad, add these two lines that you need for self-sizing cells,

self.tableView.estimatedRowHeight = 120
self.tableView.rowHeight = UITableViewAutomaticDimension // you may not need this one, I think it might be the default now

Finally, I've found that when I make the cell in the storyboard (as opposed to in code), I need to add the following method to the cell class, so the layout happens right away (otherwise it doesn't layout properly until you scroll or rotate),

override func didMoveToSuperview() {
        self.layoutIfNeeded()
    }

The problem is in your label's compression resistance: You have describe, which label is resist more to the height change: Try to set different values for the Content Hugging Priority -> Vertical and Content Compression Resistance Priority -> Vertical for the labels:

  • "Small List of Animals"
  • "List of animals"
  • "Even smaller list"

Also you use automatic UITableView cell's height calculation, but you need to setup table for it:

override func awakeFromNib() {
    super.awakeFromNib()
    tableView.estimatedRowHeight = 200; // You need approximately calculate this value by yourself, used mostly for the scroll indicator displaying
    tableView.rowHeight = UITableViewAutomaticDimension;
}

Or check your updated project https://dl.dropboxusercontent.com/u/48223929/LayoutingTest.zip

The solution is far easier than you may think. You have asked the storyboard to build a tableview with row height of 44. Select your tableView in Storyboard and check this:

旧表查看行高

You have to setup a tableView initial row height to something greater than what you may think your cell will expand, 200 for instance or even more:

建议的tableView行高

Then, when iOS tries to build a new cell with the 200 height, it fills the label, calculates the sizes, and then it shrinks the cells.

Why does this happen?

I think -not sure- the clue is the way iOS builds tableViews. iOS always shows 8-10 cells on iPhone, if the cell initially is bigger than it's real calculated height, then iOS shrinks the cell and creates/dequeues a new cell to be shown -if needed-. If the cell needs to be bigger, then iOS may need to hide a row that initially was to be shown , and then it refuses to enlarge your cell. That's why you should always prefer building larger cells than smaller ones in height.

The issue is not happening due to the modal view.

It's due to the row height you specified for the table view. Currently it's 44, change that to 200 or greater and everything will just work fine.

故事板

Also check the warnings in the Storyboard file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM