Skip to content

Instantly share code, notes, and snippets.

@JaviSoto
Created July 26, 2013 16:06
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JaviSoto/6090085 to your computer and use it in GitHub Desktop.
Save JaviSoto/6090085 to your computer and use it in GitHub Desktop.
Dynamic row height calculation in table view with cells implemented with nib + autolayout
//
// JSDynamicRowHeightTableViewController.h
//
// Created by Javier Soto on 7/25/13.
// Copyright (c) 2013 JavierSoto. All rights reserved.
//
#import <UIKit/UIKit.h>
/**
This class automatically implements `-tableView:heightForRowAtIndexPath:`. The provided cell nib (see `cellNibName`) must use autolayout.
*/
@interface JSDynamicRowHeightTableViewController : UITableViewController
/**
You must call this method as soon as the controller is instantiated to set the name of the nib that will be used for the cells of this class.
*/
@property (nonatomic, readwrite, copy) NSString *cellNibName;
/**
You can implement this simpler method to just pass information to the cell to display the appropiate contents for the index path.
@param cell The instantiated cell from the specified nib (see `-initWithStyle:cellNibName:`).
*/
- (void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
@end
//
// JSDynamicRowHeightTableViewController.m
//
// Created by Javier Soto on 7/25/13.
// Copyright (c) 2013 JavierSoto. All rights reserved.
//
#import "JSDynamicRowHeightTableViewController.h"
@interface JSDynamicRowHeightTableViewController ()
{
UITableViewCell *_cellForRowHeightCalculation;
}
@property (nonatomic, readonly, strong) UITableViewCell *cellForRowHeightCalculation;
@end
@implementation JSDynamicRowHeightTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSAssert(self.cellNibName, @"You must set the name of the nib that will be used in the cells of this controller");
UINib *cellNib = [UINib nibWithNibName:self.cellNibName
bundle:nil];
[self.tableView registerNib:cellNib
forCellReuseIdentifier:self.cellNibName];
}
- (UITableViewCell *)cellForRowHeightCalculation
{
if (!_cellForRowHeightCalculation)
{
UINib *offscreenMessageNib = [UINib nibWithNibName:self.cellNibName bundle:nil];
_cellForRowHeightCalculation = [offscreenMessageNib instantiateWithOwner:self options:nil][0];
}
return _cellForRowHeightCalculation;
}
- (void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[self doesNotRecognizeSelector:_cmd];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellNibName];
[self configureCell:cell
forRowAtIndexPath:indexPath];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *offscreenCellForHeightCalculation = self.cellForRowHeightCalculation;
CGRect cellFrame = offscreenCellForHeightCalculation.frame;
cellFrame.size.width = self.tableView.frame.size.width;
offscreenCellForHeightCalculation.frame = cellFrame;
[self configureCell:offscreenCellForHeightCalculation
forRowAtIndexPath:indexPath];
CGFloat cellHeight = [offscreenCellForHeightCalculation systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
return cellHeight;
}
@end
// Sample usage:
// 1: Create a cell "MyCell" with a nib using autolayout.
// 2: The following table view controller code will automatically size the cells according to the constraints and the content.
@interface MyTableViewController : JSDynamicRowHeightTableViewController
@end
@implementation MyTableViewController
- (id)init
{
if ((self = [super init]))
{
self.cellNibName = @"MyCell";
}
return self;
}
- (id)cellDataAtIndexPath:(NSIndexPath *)indexPath
{
return self.data[indexPath.row];
}
- (void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
id myCellData = [self cellDataAtIndexPath:indexPath];
cell.data = myCellData;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment