Created
January 8, 2015 20:46
-
-
Save jonathan-beebe/e83d7aa67dacdd4e2b70 to your computer and use it in GitHub Desktop.
Using UITableViewCell with dynamic height & autolayout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/smileyborg/TableViewCellWithAutoLayout/blob/master/TableViewCellWithAutoLayout/TableViewController/RJTableViewController.m | |
// http://stackoverflow.com/a/18746930/123781 | |
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath | |
{ | |
// This project has only one cell identifier, but if you are have more than one, this is the time | |
// to figure out which reuse identifier should be used for the cell at this index path. | |
NSString *reuseIdentifier = CellIdentifier; | |
// Use the dictionary of offscreen cells to get a cell for the reuse identifier, creating a cell and storing | |
// it in the dictionary if one hasn't already been added for the reuse identifier. | |
// WARNING: Don't call the table view's dequeueReusableCellWithIdentifier: method here because this will result | |
// in a memory leak as the cell is created but never returned from the tableView:cellForRowAtIndexPath: method! | |
RJTableViewCell *cell = [self.offscreenCells objectForKey:reuseIdentifier]; | |
if (!cell) { | |
cell = [[RJTableViewCell alloc] init]; | |
[self.offscreenCells setObject:cell forKey:reuseIdentifier]; | |
} | |
// Configure the cell for this indexPath | |
[cell updateFonts]; | |
NSDictionary *dataSourceItem = [self.model.dataSource objectAtIndex:indexPath.row]; | |
cell.titleLabel.text = [dataSourceItem valueForKey:@"title"]; | |
cell.bodyLabel.text = [dataSourceItem valueForKey:@"body"]; | |
// Make sure the constraints have been added to this cell, since it may have just been created from scratch | |
[cell setNeedsUpdateConstraints]; | |
[cell updateConstraintsIfNeeded]; | |
// The cell's width must be set to the same size it will end up at once it is in the table view. | |
// This is important so that we'll get the correct height for different table view widths, since our cell's | |
// height depends on its width due to the multi-line UILabel word wrapping. Don't need to do this above in | |
// -[tableView:cellForRowAtIndexPath:] because it happens automatically when the cell is used in the table view. | |
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds)); | |
// NOTE: if you are displaying a section index (e.g. alphabet along the right side of the table view), or | |
// if you are using a grouped table view style where cells have insets to the edges of the table view, | |
// you'll need to adjust the cell.bounds.size.width to be smaller than the full width of the table view we just | |
// set it to above. See http://stackoverflow.com/questions/3647242 for discussion on the section index width. | |
// Do the layout pass on the cell, which will calculate the frames for all the views based on the constraints | |
// (Note that the preferredMaxLayoutWidth is set on multi-line UILabels inside the -[layoutSubviews] method | |
// in the UITableViewCell subclass | |
[cell setNeedsLayout]; | |
[cell layoutIfNeeded]; | |
// Get the actual height required for the cell | |
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height; | |
// Add an extra point to the height to account for the cell separator, which is added between the bottom | |
// of the cell's contentView and the bottom of the table view cell. | |
height += 1; | |
return height; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment