on
boundingRectWithSize:options:attributes:
NSString has the method boundingRectWithSize:options:attributes: that does not quite do what one would expect. Most people expect it to return the size that you could use for drawInRect:withAttributes:. These people are normally puzzled, what to use as Option for the options: parameter and they never figure out how to make boundingRectWithSize:options:attributes: return the result for more than one line. Here’s the solution:
Both boundingRectWithSize:options:attributes: and NSAttributedString’s boundingRectWithSize:options: are intended for NSString’s drawWithRect:options:attributes: (or NSAttributedString’s drawWithRect:options:).
Example Code
NSString *header = @"your long text that should break";
NSDictionary *headerAttributes =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSColor whiteColor], NSForegroundColorAttributeName,
[NSFont systemFontOfSize:18], NSFontAttributeName,
nil];
// Setup size constraint. A 0.0 means: no constraint.
NSSize maxSize = NSMakeSize(canvasSize.width / 2, 0.0);
// NSStringDrawingUsesLineFragmentOrigin is the ONLY way to make lines break!
NSRect headerRect =
[header boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:headerAttributes];
// Relocate drawing point.
headerRect.origin.x += canvasSize.width / 2;
headerRect.origin.y += canvasSize.height - headerRect.size.height;
// Draw the text - Note NSStringDrawingUsesLineFragmentOrigin!
[header drawWithRect:headerRect
options:NSStringDrawingUsesLineFragmentOrigin
attributes:headerAttributes];
The only way to make boundingRectWithSize:options:attributes: respect the width of its size argument is using the option NSStringDrawingUsesLineFragmentOrigin. Apple did not document this for boundingRectWithSize:options:attributes: or boundingRectWithSize:options: but it is documented for drawWithRect:options:attributes: and drawWithRect:options:.