UIKit [NSString sizeWithFont: constrainedToSize:] in AppKit

Is there any equivalent method in AppKit (for Cocoa on Mac OS X) that does the same as UIKit [NSString sizeWithFont:constrainedToSize:] ?

If not, how can I get the amount of space needed to render a specific row limited by width / height?

Update: The following is a snippet of the code I'm using that I expect will produce the results I got after.

 NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: [NSFont systemFontOfSize: [NSFont smallSystemFontSize]], NSFontAttributeName, [NSParagraphStyle defaultParagraphStyle], NSParagraphStyleAttributeName, nil]; NSSize size = NSMakeSize(200.0, MAXFLOAT); NSRect bounds; bounds = [@"This is a really really really really really really really long string that won't fit on one line" boundingRectWithSize: size options: NSStringDrawingUsesFontLeading attributes: attributes]; NSLog(@"height: %02f, width: %02f", bounds.size.height, bounds.size.width); 

I would expect the width of the output file to be 200 and the height to be greater than the height of one line, however it produces:

 height: 14.000000, width: 466.619141 

Thanks!

+6
cocoa nsstring appkit
source share
6 answers

EDIT: You should be able to do something in the usual way in Lion and later. The issues described below have been fixed.


It is not possible to accurately measure text between the current Mac OS X APIs.

There are several APIs that promise to work, but do not work. This is one of them; The Core Text function for this purpose is different. Some methods return results that are close but incorrect; some return results that seem to mean nothing. I haven't submitted any errors to them yet, but when I do, I will edit the Radar numbers in this answer. You should also point out the error and include your code in a small sample project.

[Apparently, I have already submitted the main text: 8666756. It was closed as a duplicate of another unspecified error. For Cocoa, I filed 9022238 about the method proposed by Dave, and tomorrow will output two NSLayoutManager errors.]

This is the closest solution I have found.

+1
source share

Try the following:

 bounds = [value boundingRectWithSize:size options:NSLineBreakByWordWrapping | NSStringDrawingUsesLineFragmentOrigin attributes:attributes]; 
+13
source share

The newer API of the NSExtendedStringDrawing category (methods with the NSStringDrawingOptions argument) behaves in single-line mode. If you want to measure / display in multi-line mode, you want to specify NSStringDrawingUsesLineFragmentOrigin.

+6
source share

If you want to limit the string to a specific size, you use -[NSString boundingRectWithSize:options:attributes:] . .size returned NSRect is the size you are looking for.

+1
source share

Here is a more complete example of how you can do this using boundingRectWithSize.

 // get the text field NSTextField* field = (NSTextField*)view; // create the new font for the text field NSFont* newFont = [NSFont fontWithName:@"Trebuchet MS" size:11.0]; // set the font on the text field [field setFont:newFont]; // calculate the size the textfield needs to be in order to display the text properly NSString* text = field.stringValue; NSInteger maxWidth = field.frame.size.width; NSInteger maxHeight = 20000; CGSize constraint = CGSizeMake(maxWidth, maxHeight); NSDictionary* attrs = [NSDictionary dictionaryWithObjectsAndKeys:NSFontAttributeName,newFont, nil]; NSRect newBounds = [text boundingRectWithSize:constraint options:NSLineBreakByWordWrapping | NSStringDrawingUsesLineFragmentOrigin attributes:attrs]; // set the size of the text field to the calculated size field.frame = NSMakeRect(field.frame.origin.x, field.frame.origin.y, field.frame.size.width, newBounds.size.height); 

Of course, check out the Apple documentation for more information:

+1
source share

If you are looking for documentation for NSString , you will find the NSString Application Kit Add-ons Reference, which is pretty much the same as UIKit.

 -[NSString sizeWithAttributes:] 

is the method you are looking for.

-4
source share

All Articles