UITableView dynamic cell height breaks on transition or rotation

I am currently messing around with fast and dynamic table heights. I developed a simple program for iOS8.1 on xcode6.1: https://github.com/ArtworkAD/DynamicCellTest

Thus, to achieve a cell height that stretches with the contents of the cell, I do the following:

  • labels are set to 0 in the schedule lines
  • set font labels to system
  • set limits for the label in the cell
  • add self.tableView.rowHeight = UITableViewAutomaticDimension
  • do not override heightForRowAtIndex method

Minimum code required:

 class MyTableViewController: UITableViewController { var entries:Array<String> = [String]() override func viewDidLoad() { super.viewDidLoad() //create dummy content var i = 0 while i < 10 { entries.append("\(i) Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor") entries.append("\(i+1) Lorem ipsum dolor sit amet") i = i + 2; } self.tableView.rowHeight = UITableViewAutomaticDimension } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.entries.count } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = self.tableView.dequeueReusableCellWithIdentifier("basic_cell", forIndexPath: indexPath) as UITableViewCell var label = cell.viewWithTag(13) if let unwrappedLabel = label as? UILabel { unwrappedLabel.text = self.entries[indexPath.row] } return cell } } 

The left image shows the result of the above code. The height of the cell grows with the content of the label, everything is beautiful. However, when you click on the disclosure indicator on the detailed view and return again, you get the correct image. Why is this happening?

enter image description here

A bad solution to this problem is to override these methods:

 override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) self.tableView.reloadData() } override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) self.tableView.reloadData() } override func viewDidDisappear(animated: Bool) { super.viewDidDisappear(animated) self.tableView.reloadData() } 

So the problem is solved, but does this solution seem to be wrong? A side effect of this is that when you call self.tableView.reloadData() port of the table view goes to the first cell, which does not look beautiful.

Does anyone have an idea what I'm doing wrong? Feel free to clone my repo https://github.com/ArtworkAD/DynamicCellTest and test it.

+6
source share
5 answers

Adding this, it seems that it can solve the rotation problem.

 override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { self.tableView.estimatedRowHeight = 36.5 } 

However, I have another case where there are 4 labels in the cell that have the same rotation problem, adding that this is not enough, and I ended up replacing self.tableView.estimatedRowHeight = 36.5 with reloading the visible cells.

+4
source

I just solved exactly this problem by overriding the tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) into a UITableViewDelegate object.

 func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return 200 } 

Changing the exact return value does not seem to affect. Cells are always correct on their own. I have no idea why providing the calculated height causes the autorun to start, but it does. iOS 8.1.2, Xcode 6.1.

+1
source

The link gives a good explanation of what needs to be done.

Using auto layout in a UITableView for dynamic layouts of cells and row heights in a row

For your specific problem, you are missing two lines of code.

In viewDidLoad under tableView.rowHeight add self.tableView.estimatedRowHeight = 64

The above allows you to allow tableView to assign estimated elevation values ​​for shielded cells to improve performance, and also calculates the scrollbar height.

The main problem is that you are missing unwrappedLabel.preferredMaxLayoutWidth = CGRectGetWidth(tableView.bounds) in cellForRowAtIndexPath , this tells the label its preferred maximum width so that it can calculate the height required for multi-line text. Usually you do this in a subclass of the table cell.

I tested this in your project and it works

0
source

You should set estimatedRowHeight :

 // setup automatic row height self.tableView.rowHeight = UITableViewAutomaticDimension // whatever you think is the approximate row height self.tableView.estimatedRowHeight = 44 
0
source

An alternative also appeared here http://useyourloaf.com/blog/2014/08/07/self-sizing-table-view-cells.html . The comment mentions -

Just make the cell layout your subzones before returning it from cellForRowAtIndexPath:

 [cell setNeedsDisplay]; [cell layoutIfNeeded]; 

Check this

-2
source

Source: https://habr.com/ru/post/977815/


All Articles