IOS: How to measure the width and height of a string using Quartz

core-textiosobjective cquartz-graphics

Before I ask my questions, this is from Apple's documentation re: how to determine the width of a string using Quartz:

If text measurements are important to your application, it is possible
to calculate them using Quartz 2D functions. However, you might first
consider using ATSUI, whose strength is in text layout and
measurement. ATSUI has several functions that obtain text metrics. Not
only can you obtain after-layout text metrics, but in the rare cases
you need them, you can obtain before-layout text metrics. Unlike
Quartz, for which you must perform the calculations yourself, ATSUI
computes the measurements for you. For example, you can obtain the
image bounding rectangle for text by calling the ATSUI function
ATSUMeasureTextImage.

If you decide that Quartz text suits your needs better than ATSUI (or
Cocoa), you can follow these steps to measure the width of text before
Quartz draws it:

  1. Call the function CGContextGetTextPosition to obtain the current text position.
  2. Set the text drawing mode to kCGTextInvisible using the function CGContextSetTextDrawingMode.
  3. Draw the text by calling the function CGContextShowText to draw the text at the current text position.
  4. Determine the final text position by calling the function CGContextGetTextPosition.
  5. Subtract the starting position from the ending position to determine the width of the text.

Here are my questions:

  1. Is this really the best way to determine the width of a string using Core Graphics? It seems flimsy and since my text co-exists with 2D graphical elements, I'd like to use the same context for all rendering. I was hoping there would be some compact method, like:

    CGContextGetTextWidthAndHeight(context, text);
    
  2. I read that ATSUI is outdated and going to be replaced by Core Text. Is that true and if so, is it in iOS?

Best Answer

On the iPhone SDK, there's a family of methods on NSString that provide what you want.

As of iOS 7.0, these methods are:

- boundingRectWithSize:options:attributes:context:
- sizeWithAttributes:

On older versions of iOS we had these, now deprecated:

– sizeWithFont:  
– sizeWithFont:forWidth:lineBreakMode:  
– sizeWithFont:constrainedToSize:  
– sizeWithFont:constrainedToSize:lineBreakMode:  
– sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: