Skip to content

Instantly share code, notes, and snippets.

@billymeltdown
Last active January 13, 2016 21:17
Show Gist options
  • Save billymeltdown/9084884 to your computer and use it in GitHub Desktop.
Save billymeltdown/9084884 to your computer and use it in GitHub Desktop.
NSCell - still the best way to calculate dynamic row height for wrapping text in an NSView-based NSTableView?
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row {
CGFloat minimumHeight = 20.0f;
// check the cache to avoid unnecessary recalculation
NSNumber *cachedHeight;
ZTObject *field = [self.fields objectAtIndex:row];
NSString *cacheKey = [field identifier];
if ((cachedHeight = [self.cellRowHeightsCache objectForKey:cacheKey])) {
return [cachedHeight floatValue];
}
// grab the second column, which has our potentially multi-line text
NSTableColumn *column = [tableView tableColumnWithIdentifier:FieldValueColumnIdentifier];
NSString *content = [field value];
CGFloat height = minimumHeight;
// if we have some content, see if we need to go beyond the minimum height
if (content != nil && [content length] > 0) {
NSCell *cell = [column dataCell];
cell.wraps = YES;
cell.stringValue = content;
NSRect rect = NSMakeRect(0.0, 0.0, column.width, CGFLOAT_MAX);
height = [cell cellSizeForBounds:rect].height;
}
if (height < minimumHeight) height = minimumHeight; // ensure minimum
if (height > minimumHeight) {
// look out for fudge factor by checking mod of minimum
CGFloat remainder = fmod(height, minimumHeight);
height += remainder;
}
// cache it!
[self.cellRowHeightsCache setObject:[NSNumber numberWithFloat:height]
forKey:cacheKey];
return height;
}
@billymeltdown
Copy link
Author

I am using a subclass of NSTableCellView to layout my views for this table, but I can't seem to find a better way to calculate the height here, it always seems off, even with text storage content manager classes as is often prescribed. Using modulus to adjust is probably necessary no matter what. In the end, the textField will end up using an NSTextFieldCell in the same bounds so it's all good, but I suspect there's a better solution to the problem.

@raphonic
Copy link

Just an FYI, it looks like the dataCell method has been deprecated/removed on Yosemite.

edit: It isn't removed, only deprecated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment