iOS 7 gets me a different CGSize width and height

10,438

The size: you pass in to -[UIFont fontWithName:size:] is the point size of the font.

The size you get back from -[NSString sizeWithFont:constrainedToSize:lineBreakMode:] is the actual size of the laid out glyphs from the string.

If you want a given string to be a specific size, in a specific face, you will probably have to do a Newton's-method type iteration where you change the point size you're passing in until the laid out size is close enough to what you want. (I would not expect such an operation to be fast in the general case, BTW.) It might look something like this:

NSString* theString = @"FOOBAR";
CGSize constraint = CGSizeMake(275, 12);
CGFloat desiredHeight = 12.0;
CGFloat pointSize = desiredHeight;
CGFloat actualHeight = 0;
do {
    CGSize size = [theString sizeWithFont: [UIFont fontWithName:@"Helvetica" size: pointSize] constrainedToSize: constraint lineBreakMode:NSLineBreakByTruncatingTail];
    actualHeight = size.height;
    CGFloat ratio = actualHeight / desiredHeight;
    pointSize = pointSize / ratio;
} while (fabs(actualHeight - desiredHeight) > 0.01);

PS: -[NSString sizeWithFont:constrainedToSize:lineBreakMode:] is deprecated in iOS7. Compiler tells me to use -boundingRectWithSize:options:attributes:context:] instead. Using the new recommended method, it might look like this:

NSString* theString = @"FOOBAR";
CGSize constraint = CGSizeMake(275, 12);
CGFloat desiredHeight = 12.0;
CGFloat pointSize = desiredHeight;
CGFloat actualHeight = 0;
NSStringDrawingContext* ctx = [[NSStringDrawingContext alloc] init];
do {
    CGRect br = [theString boundingRectWithSize: constraint options: 0 attributes: @{ NSFontAttributeName : [UIFont fontWithName:@"Helvetica" size: pointSize] } context:ctx];
    actualHeight = br.size.height;
    CGFloat ratio = actualHeight / desiredHeight;
    pointSize = pointSize / ratio;
} while (fabs(actualHeight - desiredHeight) > 0.01);
Share:
10,438

Related videos on Youtube

JackoJack
Author by

JackoJack

Updated on September 26, 2022

Comments

  • JackoJack
    JackoJack over 1 year

    I have a problem on my app on iOS 7

    I calculate my label size using:

    CGSize constraint = CGSizeMake(275, 141);
    CGSize size;
    
    size = [_rtLabelQuestion.plainText sizeWithFont:[UIFont fontWithName:@"KGWhattheTeacherWants" size:intFont] constrainedToSize:constraint lineBreakMode:NSLineBreakByTruncatingTail];
    

    and then place my label frame using:

    _rtLabelQuestion.frame = CGRectMake(aLabelTemp.frame.origin.x, aLabelTemp.frame.origin.y, size.width + 2 , size.height + 10);
    

    But on iOS 7 width and height of my CGSize is always smaller from exactly intFont pixels, i've been working on that 2 days and no solution, please help, thank you !

  • JackoJack
    JackoJack over 10 years
    what is a Newton's method type iteration ? too complicated for me. but thanks
  • JackoJack
    JackoJack over 10 years
    Thank you very much ipmcc i'll give a try.
  • JackoJack
    JackoJack over 10 years
    Well it's too complicated for me to user NSSTringDrawingContext, i think system Font on iOS6 and iOS 7 are different. i do not understand, i'm in big trouble, but thank you for time and answer