Enchilada Enchilada - 3 months ago 33
Objective-C Question

*Accurately* calculating text height in Cocoa (for Mac, not iOS)

How can I calculate the height of a string within a particular label (NSTextField), for some given fixed width?

I tried Googling up various methods. I tried this method: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight.html

It works, except that the height becomes one line too short for longer strings. Thus, there appear to be some inaccuracies in the present methods.

I also had the same issue with some other code I Googled up.

Does someone here have any accurate code for finding text height (given a particular width)?


I solved the problem using the NS(Attributed)String+Geometrics category provided at http://www.sheepsystems.com/sourceCode/sourceStringGeometrics.html Within the header file of that category is a good explanation of how these things work. Specifically, they mention that one should use NSTextView instead of NSTextField because it's virtually impossible to get an accurate height for the latter.

Thus, I replaced my NSTextField with NSTextView. First, I made my NSTextView look like my NSTextField with this code:

[textView setEditable:YES];
[textView insertText:someString];
[textView setFont:[NSFont fontWithName:@"Lucida Grande"
   size:11] range:NSMakeRange(0,[someString length])];
[textView setEditable:NO];
[textView setSelectable:NO];

Then I got the height with this code:

NSDictionary *attributes
  = [NSDictionary dictionaryWithObjectsAndKeys:
     [textView font],NSFontAttributeName,nil];
NSAttributedString *attributedString
  = [[NSAttributedString alloc] initWithString:
     [textView string] attributes:attributes];
CGFloat height = [attributedString heightForWidth:
                 [textView frame].size.width];

The height does indeed turn out to be accurate for NSTextView.

I may have omitted some minor details, but you get the picture. I hope this helps someone out there.