bounding​Rect​With​Size:​options:​attributes:

NSString has the method bounding​Rect​With​Size:​options:​attributes: that does not quite do what one would expect. Most people expect it to return the size that you could use for draw​In​Rect:​with​Attributes:. These people are normally puzzled, what to use as Option for the options: parameter and they never figure out how to make bounding​Rect​With​Size:​options:​attributes: return the result for more than one line. Here’s the solution:

Both bounding​Rect​With​Size:​options:​attributes: and NSAttributedString’s bounding​Rect​With​Size:​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 bounding​Rect​With​Size:​options:​attributes: respect the width of its size argument is using the option NSString​Drawing​Uses​Line​Fragment​Origin. Apple did not document this for bounding​Rect​With​Size:​options:​attributes: or bounding​Rect​With​Size:​options: but it is documented for draw​With​Rect:​options:​attributes: and draw​With​Rect:​options:.