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:
.