Multiline UILabel with adjustsFontSizeToFitWidth

前端 未结 8 1502
北海茫月
北海茫月 2020-12-04 12:16

I have a multiline UILabel whose font size I\'d like to adjust depending on the text length. The whole text should fit into the label\'s frame without truncating it.

8条回答
  •  不思量自难忘°
    2020-12-04 13:01

    Thanks, with that and a little more from someone else I did this custom UILabel, that will respect the minimum font size and there's a bonus option to align the text to top.

    h:

    @interface EPCLabel : UILabel {
        float originalPointSize;
        CGSize originalSize;
    }
    
    @property (nonatomic, readwrite) BOOL alignTextOnTop;
    @end
    

    m:

    #import "EPCLabel.h"
    
    @implementation EPCLabel
    @synthesize alignTextOnTop;
    
    -(void)verticalAlignTop {
        CGSize maximumSize = originalSize;
        NSString *dateString = self.text;
        UIFont *dateFont = self.font;
        CGSize dateStringSize = [dateString sizeWithFont:dateFont 
                                       constrainedToSize:CGSizeMake(self.frame.size.width, maximumSize.height)
                                           lineBreakMode:self.lineBreakMode];
    
        CGRect dateFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, dateStringSize.height);
    
        self.frame = dateFrame;
    }
    
    - (CGFloat)fontSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size {
        CGFloat fontSize = [font pointSize];
        CGFloat height = [self.text sizeWithFont:font             
                               constrainedToSize:CGSizeMake(size.width,FLT_MAX)  
                                   lineBreakMode:UILineBreakModeWordWrap].height;
        UIFont *newFont = font;
    
        //Reduce font size while too large, break if no height (empty string)
        while (height > size.height && height != 0 && fontSize > self.minimumFontSize) { 
            fontSize--;  
            newFont = [UIFont fontWithName:font.fontName size:fontSize];   
            height = [self.text sizeWithFont:newFont  
                           constrainedToSize:CGSizeMake(size.width,FLT_MAX) 
                               lineBreakMode:UILineBreakModeWordWrap].height;
        };
    
        // Loop through words in string and resize to fit
        if (fontSize > self.minimumFontSize) {
            for (NSString *word in [self.text componentsSeparatedByString:@" "]) {
                CGFloat width = [word sizeWithFont:newFont].width;
                while (width > size.width && width != 0 && fontSize > self.minimumFontSize) {
                    fontSize--;
                    newFont = [UIFont fontWithName:font.fontName size:fontSize];   
                    width = [word sizeWithFont:newFont].width;
                }
            }
        }
        return fontSize;
    }
    
    -(void)setText:(NSString *)text {
        [super setText:text];
        if (originalSize.height == 0) {
            originalPointSize = self.font.pointSize;
            originalSize = self.frame.size;
        }
    
        if (self.adjustsFontSizeToFitWidth && self.numberOfLines > 1) {
            UIFont *origFont = [UIFont fontWithName:self.font.fontName size:originalPointSize];
            self.font = [UIFont fontWithName:origFont.fontName size:[self fontSizeWithFont:origFont constrainedToSize:originalSize]];
        }
    
        if (self.alignTextOnTop) [self verticalAlignTop];
    }
    
    -(void)setAlignTextOnTop:(BOOL)flag {
        alignTextOnTop = YES;
        if (alignTextOnTop && self.text != nil)
            [self verticalAlignTop];
    }
    
    @end
    

    I hope it helps.

提交回复
热议问题