Daryl Spitzer
Daryl Spitzer

Reputation: 149364

How do I get -[NSString sizeWithFont:forWidth:lineBreakMode:] to work?

I updated my question "Sizing a UILabel (in the iPhone SDK) to fit?" with a description of my problem with a suggested solution, but didn't get an answer. Perhaps I'll have better results by asking a new question...

I set a breakpoint after the following code:

NSString *theText = @"When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.";
CGSize theSize = [theText sizeWithFont:[UIFont systemFontOfSize:17.0f] forWidth:260.0 lineBreakMode:UILineBreakModeWordWrap];

theSize.height is 21 and theSize.width is 231. What am I doing wrong? That height can't be in pixels nor in number of lines.

Note that [UIFont systemFontOfSize:17.0f] is meant to specify the default font.

Update: I changed the code to:

CGSize constraintSize;
constraintSize.width = 260.0f;
constraintSize.height = MAXFLOAT;
NSString *theText = @"When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.";
CGSize theSize = [theText sizeWithFont:[UIFont systemFontOfSize:17.0f] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

theSize.height is 273. That seems more like it.

Upvotes: 21

Views: 35242

Answers (2)

Matt Weaver
Matt Weaver

Reputation: 119

As anyone who has puzzled this out learns, the method is inappropriately named and rather inconsistent with what you'd expect (that's a violation of good API design, but as any seasoned dev knows: Apple's API is not well designed, sorry guys). Worth reading: Josh Bloch's presentation on good API design.

I'd posit that they should rename it (if it must be kept) and make this one useful, such that you don't end up using the common practice of passing in a CGSize with a size you know is much too large.

[someString sizeWithFont:yourFont 
       constrainedToSize:CGSizeMake(maxWidthYouSpecify, self.frame.size.height)  
           lineBreakMode:UILineBreakModeWordWrap];

Alternately this would work just as well:

[someString sizeWithFont:yourFont 
       constrainedToSize:CGSizeMake(maxWidthYouSpecify, CGFLOAT_MAX)
           lineBreakMode:UILineBreakModeWordWrap];

This is, arguably, how the function should work. (FWIW, CGFLOAT_MAX is defined in CGGeometry)

An aside, but rather important: all Core Graphics deal in points not pixels.

One point does not necessarily correspond to one pixel on the screen.

That's an important distinction and one you need to understand when dealing with different resolutions (iPhone 3GS vs 4 vs iPad, etc). See Apple's docs and Command+F for "Points vs Pixels".

Upvotes: 7

Lily Ballard
Lily Ballard

Reputation: 185671

That height is in pixels. I expect it's truncating, i.e. giving you the metrics you'd see if you set this text on a UILabel with 1 line.

Try using sizeWithFont:constrainedToSize: and just give it MAXFLOAT for the height component of the size.

Upvotes: 29

Related Questions