How to adjust font size of label to fit the rectangle?

前端 未结 14 771
独厮守ぢ
独厮守ぢ 2020-11-28 07:00

Yeah, there\'s this cool myLabel.adjustsFontSizeToFitWidth = YES; property. But as soon as the label has two lines or more, it won\'t resize the text to anythin

14条回答
  •  悲哀的现实
    2020-11-28 07:00

    All binary searches are good, but stop recursion using frame checks not so logically. More nicely check font size, cause UIFont supports float size and this font is more suitable. Plus using label paragraph style to calculate size morу exactly.

    If someone interesting, you can look bellow code:

    static UIFont * ___suitableFontInRangePrivate(const CGSize labelSize,
                                                NSParagraphStyle * paragraphStyle,
                                                NSString * fontName,
                                                NSString * text,
                                                const CGFloat minSize,
                                                const CGFloat maxSize)
    {
        // Font size in range, middle size between max & min.
        const CGFloat currentSize = minSize + ((maxSize - minSize) / 2);
    
        // Font with middle size.
        UIFont * currentFont = [UIFont fontWithName:fontName size:currentSize];
    
        // Calculate text height.
        const CGFloat textHeight = [text boundingRectWithSize:CGSizeMake(labelSize.width, CGFLOAT_MAX)
                                                    options:NSStringDrawingUsesLineFragmentOrigin
                                                attributes:@{ NSFontAttributeName : currentFont, NSParagraphStyleAttributeName : paragraphStyle }
                                                    context:nil].size.height;
        CGFloat min, max;
        if (textHeight > labelSize.height)
        {
            // Take left range part.
            min = minSize;
            max = currentSize;
        }
        else
        {
            // Take right range part.
            min = currentSize;
            max = maxSize;
        }
    
        // If font size in int range [0.0; 2.0] - got it, othervice continue search.
        return ((max - min) <= 2.0) ? currentFont : ___suitableFontInRangePrivate(labelSize, paragraphStyle, fontName, text, min, max);
    }
    
    void UILabelAdjustsFontSizeToFrame(UILabel * label)
    {
        if (!label) return;
    
        NSString * text = [label text];
    
        __block NSParagraphStyle * style = nil;
        [[label attributedText] enumerateAttributesInRange:NSMakeRange(0, [text length])
                                                options:(NSAttributedStringEnumerationOptions)0
                                                usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop){
                                                    id paragraphStyle = [attrs objectForKey:@"NSParagraphStyle"];
                                                    if (paragraphStyle) style = [paragraphStyle retain];
                                                }];
    
        if (!style)
        {
            NSMutableParagraphStyle * paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
            if (!paragraphStyle) paragraphStyle = [[NSMutableParagraphStyle alloc] init];
            if (paragraphStyle)
            {
                [paragraphStyle setLineBreakMode:[label lineBreakMode]];
                [paragraphStyle setAlignment:[label textAlignment]];
            }
            style = paragraphStyle;
        }
    
        UIFont * suitableFont = ___suitableFontInRangePrivate([label frame].size, style, [[label font] fontName], text, 0, 500);
        [label setFont:suitableFont];
        [style release];
    }
    

提交回复
热议问题