问题描述:

I need to fit a multiline attributed text in a UILabel's frame.

Reading this thread How to adjust font size of label to fit the rectangle? I started from Niels' solution in order to work with attributed text.

Here's the code: the 't' of 'prospect' is put in a new line, whereas I need the words not to be truncated; in this example I expect the font size to be reduced a little more in order to fit 'prospect in a single line.

UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 180, 180)];

myLabel.font = [UIFont fontWithName:@"Arial" size:5];

myLabel.adjustsFontSizeToFitWidth = YES;

myLabel.backgroundColor = [UIColor orangeColor];

myLabel.numberOfLines = -1;

myLabel.lineBreakMode = NSLineBreakByWordWrapping;

NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];

[paragraphStyle setLineSpacing:8];

[paragraphStyle setAlignment:NSTextAlignmentLeft];

NSDictionary *attributes = @{ NSFontAttributeName:myLabel.font, NSParagraphStyleAttributeName: paragraphStyle };

NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:@"New Prospect" attributes:attributes];

myLabel.attributedText = attributedString;

myLabel.font = [UIFont fontWithName:@"Arial" size:160];

[self sizeLabel:myLabel toRect:myLabel.frame];

[self.view addSubview:myLabel];

The sizeLabel method is implemented as follows:

- (void) sizeLabel {

int fontSize = self.font.pointSize;

int minFontSize = 5;

// Fit label width wize

CGSize constraintSize = CGSizeMake(self.frame.size.width, MAXFLOAT);

do {

// Set current font size

self.font = [UIFont fontWithName:self.font.fontName size:fontSize];

// Find label size for current font size

CGRect textRect = [[self attributedText] boundingRectWithSize:constraintSize

options:NSStringDrawingUsesLineFragmentOrigin

context:nil];

CGSize labelSize = textRect.size;

// Done, if created label is within target size

if( labelSize.height <= self.frame.size.height )

break;

// Decrease the font size and try again

fontSize -= 2;

} while (fontSize > minFontSize);

}

Any idea?

Thanks,

DAN

网友答案:

You also need to check every words to be sure they aren't being truncated, since boundingRectWithSize: will never return a CGRect wider than the width you provided (even if a single word doesn't fit in the width). Here is a similar loop with that mechanic in place:

- (void)setButtonTitle:(NSString *)title
{
    CGFloat fontSize = 20; // The max font size you want to use
    CGFloat minimumFontSize = 5; // The min font size you want to use
    CGFloat labelHeightWithFont = 0;
    CGFloat longestWordWidth = 0;
    UIFont *labelFont = nil;

    CGFloat buttonLabelMaxWidth = self.size.width;

    do {

        if (fontSize < minimumFontSize) {
            // Handle exception where the title just won't fit
            break;
        }

        // Trying the current font size if it fits
        labelFont = [UIFont systemFontOfSize:fontSize--];
        CGSize boundingSize = [self boundingSizeForString:title font:labelFont];
        labelHeightWithFont = boundingSize.height;

        // Be sure that words are not truncated (that they fits in the maximum width)
        longestWordWidth = 0;
        for (NSString *word in [title componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]) {
            CGSize wordSize = [word sizeWithAttributes:@{NSFontAttributeName: labelFont}];
            longestWordWidth = MAX(longestWordWidth, wordSize.width);
        }

        // Loop until the text at the current size fits the maximum width/height.
    } while (labelHeightWithFont > buttonLabelMaxWidth || longestWordWidth > buttonLabelMaxWidth);

    self.buttonLabel.text = title;
    self.buttonLabel.font = labelFont;
}

- (CGSize)boundingSizeForString:(NSString *)string font:(UIFont *)font
{

    CGRect boundingRect = [string boundingRectWithSize:CGSizeMake([self buttonLabelMaxWidth], MAXFLOAT)
                                options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                             attributes:@{NSFontAttributeName: font}
                                context:nil];
    return CGSizeMake(ceilf(boundingRect.size.width), ceilf(boundingRect.size.height));
}
相关阅读:
Top