iOS 7 sizeWithAttributes: replacement for sizeWithFont:constrainedToSize

Objective CIos7

Objective C Problem Overview


How do you return a multiline text CGSize from the new iOS 7 method sizeWithAttributes?

I would like this to produce the same results as sizeWithFont:constrainedToSize.

NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu urna quis lacus imperdiet scelerisque a nec neque. Mauris eget feugiat augue, vitae porttitor mi. Curabitur vitae sollicitudin augue. Donec id sapien eros. Proin consequat tellus in vehicula sagittis. Morbi sed felis a nibh hendrerit hendrerit. Lorem ipsum dolor sit."

CGSize textSize = [text sizeWithAttributes:@{ NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-Light" size:16.0] }];

This method only produces the height for a single line of text.

Objective C Solutions


Solution 1 - Objective C

well you can try this :

NSDictionary *attributes = @{NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:14]};
// NSString class method: boundingRectWithSize:options:attributes:context is
// available only on ios7.0 sdk.
CGRect rect = [textToMeasure boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX)
                                          options:NSStringDrawingUsesLineFragmentOrigin
                                       attributes:attributes
                                          context:nil];

  

Solution 2 - Objective C

This is how I did it:

    // Get a font to draw it in
UIFont *font = [UIFont boldSystemFontOfSize: 28];

CGRect textRect;
NSDictionary *attributes = @{NSFontAttributeName: font};

// How big is this string when drawn in this font?
textRect.size = [text sizeWithAttributes:attributes];

// Draw the string
[text drawInRect:textRect withAttributes:attributes];

Solution 3 - Objective C

Here's my method to deal with both situations, goes in an NSString category.

- (CGSize) sizeWithFontOrAttributes:(UIFont *) font {
    if (IS_IOS7) {
        NSDictionary *fontWithAttributes = @{NSFontAttributeName:font};
        return [self sizeWithAttributes:fontWithAttributes];
    } else {
        return [self sizeWithFont:font];
    }
}

Solution 4 - Objective C

For Xamarin.iOS:

UIFont descriptionLabelFont =  UIFont.SystemFontOfSize (11);
NSString textToMeasure = (NSString)DescriptionLabel.Text;

CGRect labelRect = textToMeasure.GetBoundingRect (
	new CGSize(this.Frame.Width, nfloat.MaxValue), 
	NSStringDrawingOptions.UsesLineFragmentOrigin, 
	new UIStringAttributes () { Font = descriptionLabelFont }, 
	new NSStringDrawingContext ()
);

Solution 5 - Objective C

Swift 2.3:

let attributes = [NSFontAttributeName:UIFont(name: "HelveticaNeue", size: 14)]
let rect = NSString(string: textToMeasure).boundingRectWithSize(
        CGSizeMake(width, CGFLOAT_MAX), 
        options: NSStringDrawingOptions.UsesLineFragmentOrigin, 
        attributes: attributes, context: nil)

Swift 4:

let attributes = [NSFontAttributeName:UIFont(name: "HelveticaNeue", size: 14)]
let rect = NSString(string: textToMeasure).boundingRect(
                    with: CGSize(width: width, height: CGFloat.greatestFiniteMagnitude),
                    options: NSStringDrawingOptions.usesLineFragmentOrigin,
                    attributes: attributes as [NSAttributedString.Key : Any], context: nil)

Solution 6 - Objective C

If you have the text, font, numberOfLines and width of your label set, this method returns the size of your label:

myLabel.numberOfLines = 0;

CGSize size = [myLabel sizeThatFits:CGSizeMake(myLabel.frame.size.width, CGFLOAT_MAX)];`

Solution 7 - Objective C

As an alternative, if you're looking at UITextView, you can always use the NSLayoutManager method:

CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size;

You can also find the line height for a given font by:

UIFont *font;
CGFloat lineHeight = font.lineHeight;

Solution 8 - Objective C

[As a new user, I cannot post a comment to @testing's answer, but to make his answer (for xamarin.ios) more useful]

We can return a CGRect and only use the height parameter for the gui item we are targeting UIButton etc.Passing in any parameters we need as below

    public CGRect GetRectForString(String strMeasure, int fontSize, nfloat guiItemWidth)
    {
        UIFont descriptionLabelFont =  UIFont.SystemFontOfSize (fontSize);
        NSString textToMeasure = (NSString)strMeasure;
      
        CGRect labelRect = textToMeasure.GetBoundingRect (
            new CGSize(guiItemWidth, nfloat.MaxValue), 
            NSStringDrawingOptions.UsesLineFragmentOrigin, 
            new UIStringAttributes () { Font = descriptionLabelFont }, 
            new NSStringDrawingContext ()
        );

        return labelRect;
    }

        header_Revision.Frame = new CGRect (5
                                            , verticalAdjust
                                            , View.Frame.Width-10
                                            , GetRectForString( header_Revision.Title(UIControlState.Normal)
                                                              , 18
                                                              , View.Frame.Width-10 ).Height
                                            );

Solution 9 - Objective C

CGSize stringsize = [lbl.text sizeWithAttributes:
                         @{NSFontAttributeName:[UIFont fontWithName:FontProximaNovaRegular size:12.0]}];


CGSize adjustedSize = CGSizeMake(ceilf(stringsize.width), ceilf(stringsize.height));

use ceilf method to manage properlly

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmorcuttView Question on Stackoverflow
Solution 1 - Objective CoiledCodeView Answer on Stackoverflow
Solution 2 - Objective CGnawboneView Answer on Stackoverflow
Solution 3 - Objective CDan RosenstarkView Answer on Stackoverflow
Solution 4 - Objective CtestingView Answer on Stackoverflow
Solution 5 - Objective CJellyView Answer on Stackoverflow
Solution 6 - Objective CMarijnView Answer on Stackoverflow
Solution 7 - Objective CmikehoView Answer on Stackoverflow
Solution 8 - Objective CMattView Answer on Stackoverflow
Solution 9 - Objective CjenishView Answer on Stackoverflow