Usually my approach to supporting variable height cells is to define a class method that can calculate the size for a given model object:
+ (CGFloat)heightForBracket:(Bracket*)bracket;
The beauty of creating a class method is that you can share constants (pad values, font sizes, indentation levels, etc.) with code that actually implements the layout without exposing them to other classes. If you want to change these constants in the future, you only need to make changes in one place in the cell subclass. Subclass implementation example:
#define kPaddingHorizontal 10.0 #define kPaddingVertical 10.0 #define kFontSizeName 17.0 + (CGFloat)heightForBracket:(Bracket*)bracket {
Then you can call heightForBracket: in tableView:heightForRowAtIndexPath: ::
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { Bracket *bracket = [brackets objectAtIndex:indexPath.row]; return [BracketTableCell heightForBracket:bracket]; }
tableView:cellForRowAtIndexPath: becomes very simple, just set the appropriate cell in the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"BCell"; BracketTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[BracketTableCell alloc] initWithReuseIdentifier:CellIdentifier]; } Bracket *bracket = [brackets objectAtIndex:indexPath.row]; cell.bracket = bracket; return cell; }
A few notes:
- this assumes that the cell does not use automatic layout
- this clearly hardcodes the width of the cell / label, which may or may not be suitable for your use.
- you should never call the
description property because it is a method that already exists in the NSObject protocol - Other improvements will cache the result of
heightForBracket: to improve scroll performance, especially if you start to perform calibration logic for a ton of subview
source share