Skip to content

Instantly share code, notes, and snippets.

@andrewsardone
Created October 4, 2012 18:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewsardone/3835403 to your computer and use it in GitHub Desktop.
Save andrewsardone/3835403 to your computer and use it in GitHub Desktop.
-[UITableViewDelegate tableView:heightForRowAtIndexPath:] calculation with n-number of side-by-side content views (like the textLabel and detailTextLabel)
// ...
#pragma mark UITableViewDelegate methods
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *attributes = [NSMutableArray array];
id labelAttributes = @{
UITableViewCellNLHeightAttributeText: [self textLabelTextAtIndexPath:indexPath],
UITableViewCellNLHeightAttributeFont: [self fontForTextLabel],
UITableViewCellNLHeightAttributeConstrainingSize: [NSValue valueWithCGSize:CGSizeMake(67.0, NSIntegerMax)],
UITableViewCellNLHeightAttributeLineBreakMode: @(NSLineBreakByWordWrapping)
};
[attributes addObject:labelAttributes];
CGFloat detailWidth = tableView.isEditing ? 174 : 206;
id valueAttributes = @{
UITableViewCellNLHeightAttributeText: [self detailTextLabelTextAtIndexPath:indexPath],
UITableViewCellNLHeightAttributeFont: [self fontForDetailTextLabel],
UITableViewCellNLHeightAttributeConstrainingSize: [NSValue valueWithCGSize:CGSizeMake(detailWidth, NSIntegerMax)],
UITableViewCellNLHeightAttributeLineBreakMode: @(NSLineBreakByWordWrapping)
};
[attributes addObject:valueAttributes];
return [UITableViewCell nl_heightForCellWithAttributes:attributes];
}
// ...
#import <UIKit/UIKit.h>
@interface UITableViewCell (NLCalculations)
/**
* Returns the fitted height of a `UITableViewCell` for the given series of
* attributes (text, font, etc.) representing properties on series of side-by-side
* content view subviews. The tallest size is what wins!
*
* @param attributes
* An `NSArray` of `NSDictionary` descriptions of the views' text, font,
* constraining size, and line break mode. The dictionary takes the
* following form:
*
* {
* UITableViewCellNLHeightAttributeText: NSString
* UITableViewCellNLHeightAttributeFont: UIFont
* UITableViewCellNLHeightAttributeConstrainingSize: CGSize,
* UITableViewCellNLHeightAttributeLineBreakMode: NSLineBreakMode
* }
*
* @discussion This function can be used within a `UITableViewDelegate` implementation
* that needs to dynamically size up the height of various cells that
* have content views side-by-side, e.g., the `textLabel` and
* `detailTextLabel` of a `UITableViewCell` initialized with the
* `UITableViewCellStyleValue2` cell style.
*
* - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
* {
* NSMutableArray *attributes = [NSMutableArray array];
*
* id textLabelAttributes = @{
* UITableViewCellNLHeightAttributeText: [self textLabelTextAtIndexPath:indexPath],
* UITableViewCellNLHeightAttributeFont: [self fontForTextLabel],
* UITableViewCellNLHeightAttributeConstrainingSize: [NSValue valueWithCGSize:CGSizeMake(67.0, NSIntegerMax)],
* UITableViewCellNLHeightAttributeLineBreakMode: @(NSLineBreakByWordWrapping)
* };
* [attributes addObject:textLabelAttributes];
*
* id detailTextLabelAttributes = @{
* UITableViewCellNLHeightAttributeText: [self detailTextLabelTextAtIndexPath:indexPath],
* UITableViewCellNLHeightAttributeFont: [self fontForDetailTextLabel],
* UITableViewCellNLHeightAttributeConstrainingSize: [NSValue valueWithCGSize:CGSizeMake(206.0, NSIntegerMax)],
* UITableViewCellNLHeightAttributeLineBreakMode: @(NSLineBreakByWordWrapping)
* };
* [attributes addObject:detailTextLabelAttributes];
*
* return [UITableViewCell nl_heightForCellWithAttributes:attributes];
* }
*
*/
+ (CGFloat)nl_heightForCellWithAttributes:(NSArray *)attributes;
extern NSString *UITableViewCellNLHeightAttributeText;
extern NSString *UITableViewCellNLHeightAttributeFont;
extern NSString *UITableViewCellNLHeightAttributeConstrainingSize;
extern NSString *UITableViewCellNLHeightAttributeLineBreakMode;
@end
#import "UITableViewCell+NLCalculations.h"
@implementation UITableViewCell (NLCalculations)
+ (CGFloat)nl_heightForCellWithAttributes:(NSArray *)attributes
{
static CGFloat DefaultCellHeight = 44.0;
static CGFloat DefaultCellPadding = 10.0;
NSMutableArray *heights = [NSMutableArray array];
[heights addObject:@(DefaultCellHeight)];
for (NSDictionary *attr in attributes)
{
NSString *text = attr[UITableViewCellNLHeightAttributeText];
UIFont *font = attr[UITableViewCellNLHeightAttributeFont];
NSValue *valueContraint = attr[UITableViewCellNLHeightAttributeConstrainingSize];
CGSize constraint = (valueContraint) ? valueContraint.CGSizeValue : CGSizeZero;
NSLineBreakMode lineBreakMode = [attr[UITableViewCellNLHeightAttributeLineBreakMode] integerValue];
CGSize constrainedSize = [text sizeWithFont:font
constrainedToSize:constraint
lineBreakMode:lineBreakMode];
CGFloat height = constrainedSize.height + (DefaultCellPadding * 2);
[heights addObject:@(height)];
}
NSNumber *maxHeight = [heights valueForKeyPath:@"@max.floatValue"];
CGFloat maxHeightFloat = maxHeight.floatValue;
return maxHeightFloat;
}
NSString *UITableViewCellNLHeightAttributeText = @"UITableViewCellNLHeightAttributeText";
NSString *UITableViewCellNLHeightAttributeFont = @"UITableViewCellNLHeightAttributeFont";
NSString *UITableViewCellNLHeightAttributeConstrainingSize = @"UITableViewCellNLHeightAttributeConstrainingSize";
NSString *UITableViewCellNLHeightAttributeLineBreakMode = @"UITableViewCellNLHeightAttributeLineBreakMode";
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment