Prefix Prefix - 4 months ago 14
iOS Question

how to set table cell height dynamically depending on text label length?

I am trying to learn Obj-C and iOS programming, but am still very new. I decided to try and make a simple Reddit client application. I am trying to display the front page posts within a

UITableView
, with each post represented by its own cell.

On the cell, here is how I am setting the title:

cell.textLabel.numberOfLines = 0;
cell.textLabel.text = [[tempDictionary objectForKey:@"data"] objectForKey:@"title"];
[cell.textLabel sizeToFit];


However, the cell ends up clipping itself if the title text is too long. Here's a picture:

enter image description here

How can I make my cells automatically adjust their heights to accommodate longer title labels, without intersecting other cells or the detail text label?

Thank you for any help!

Answer

For new iOS 8 there is a new way to make this simple.

There is new a parameter that calculates your cell height with respect of your auto layout constraints. This is UITableViewAutomaticDimension. You can use it in the viewWillAppear method of your view controller.

Objective C:

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  self.tableView.estimatedRowHeight = 70.0; // for example. Set your average height 
  self.tableView.rowHeight = UITableViewAutomaticDimension;
  [self.tableView reloadData];
}

Swift:

override func viewWillAppear(animated: Bool) {
    self.tableView.estimatedRowHeight = 70 // for example. Set your average height 
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.reloadData()

} 

Work nice and as you want at your example. As for me, I add height things in viewDidLoad and left in viewWillAppear only reloadData(). There is also useful source.

From documentation: The default value of rowHeight is UITableViewAutomaticDimension. I leave the code as it is, for now, but keep in mind that you don't need to set row height in iOS 8+.

The main thing you need to do is to set all constraints explicitly e.g. to the leading, trailing, top and bottom. Try it first, without adding any lines of code above.