Is there any equivalent method in AppKit (for Cocoa on Mac OS X) that does the same thing as UIKit\'s [NSString sizeWithFont:constrainedToSize:]
?
If not
If you want to constrain the string to a certain size, you use -[NSString boundingRectWithSize:options:attributes:]. The .size
of the returned NSRect
is the size you're looking for.
Try this one:
bounds = [value boundingRectWithSize:size options:NSLineBreakByWordWrapping | NSStringDrawingUsesLineFragmentOrigin attributes:attributes];
The newer NSExtendedStringDrawing category API (methods with the NSStringDrawingOptions argument) behaves in the single line mode. If you want to measure/render in multi line mode, want to specify NSStringDrawingUsesLineFragmentOrigin.
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, for additional info, take a look at the Apple documentation:
EDIT: You should be able to do things the normal way in Lion and later. The problems described below have been fixed.
There is no way to accurately measure text among the current Mac OS X APIs.
There are several APIs that promise to work but don't. That's one of them; Core Text's function for this purpose is another. Some methods return results that are close but wrong; some return results that seem to mean nothing at all. I haven't filed any bugs on these yet, but when I do, I'll edit the Radar numbers into this answer. You should file a bug as well, and include your code in a small sample project.
[Apparently I have already filed the Core Text one: 8666756. It's closed as a duplicate of an unspecified other bug. For Cocoa, I filed 9022238 about the method Dave suggested, and will file two NSLayoutManager bugs tomorrow.]
This is the closest solution I've found.
If you search the documentation for NSString
, you will find the "NSString Application Kit Additions Reference", which is pretty much analogous to the UIKit counterpart.
-[NSString sizeWithAttributes:]
is the method you are looking for.