2
votes

I want to draw a string in a single line on a UIView that fits the width of the given rect(much like what adjustsFontSizeToFitWidth for a UILabel does when number of lines = 1). I'm trying to calculate the font size that will fit the rect as below.

    - (UIFont *)fontforWidth:(CGFloat)width String:(NSString *)stringToFit {

    CGFloat widthForIdealFontSize = [self widthForIdealFontSizeWithString:stringToFit];
    CGFloat requiredFontSize = (KIdealFontSize/widthForIdealFontSize*width);

    return [UIFont fontWithName:self.fontName size:(requiredFontSize)];
    }

    - (CGFloat)widthForIdealFontSizeWithString:(NSString *)inputString         {

    NSAttributedString *attrString = [[NSAttributedString alloc]initWithString:inputString attributes:@{NSFontAttributeName:[UIFont fontWithName:self.fontName size:KIdealFontSize]}];
    CTLineRef line = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)attrString);

    CGFloat ascent, descent, leading;
    CGFloat width = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
    return width;

    }

where #define KIdealFontSize 1000. I'm not able to get the exact value of the font size for some fonts like Zapfino where the string gets clipped when drawn. Is there a better way to calculate the exact font size that will fit the width for all fonts?

1

1 Answers

0
votes

i have indirect solution for that

- (NSString *) calculateNUmberOFCharacters:(NSString *)orignalString size:(CGSize )size andFont:(UIFont *)font {

float oneLineHeight = [self getHeightForText:@"Test" withFont:font andWidth:size.width];

NSString *outputString = @"";
if (orignalString.length) {

    if ([self getHeightForText:orignalString withFont:font andWidth:size.width] > oneLineHeight) {

        NSArray *arrValues = [orignalString componentsSeparatedByString:@" "];
        __block NSString *oldString;
        for (NSString *obj in arrValues) {
            oldString = outputString;
            outputString = [outputString stringByAppendingString:[NSString stringWithFormat:@"%@ ",obj]];

            if ([self getHeightForText:outputString withFont:font andWidth:size.width] > oneLineHeight) {
                NSLog(@"%@",oldString);
                return oldString;
            }
        }
    }
    return orignalString;
}
return nil;

}

Pass your string , width and font it will return you string

match your original string with value that returns

if match then you got your string match that width else pass with event small fonts in it

it is long process but working

-(float) getHeightForText:(NSString*) text withFont:(UIFont*) font andWidth:(float) width{
CGSize constraint = CGSizeMake(width , 20000.0f);
CGSize title_size;
float totalHeight;
title_size = [text boundingRectWithSize:constraint
                                options:NSStringDrawingUsesLineFragmentOrigin
                             attributes:@{ NSFontAttributeName : font }
                                context:nil].size;

totalHeight = ceil(title_size.height);

CGFloat height = MAX(totalHeight, 10.0f);

return height;

}