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

前端 未结 14 764
独厮守ぢ
独厮守ぢ 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:16

    I found Niels' answer to be the best answer for this issue. However, I have a UIView that can have 100 labels where I need to fit the text, so this process was very inefficient and I could feel the hit in performance.

    Here is his code modified to use a binary search instead, rather than a linear search. Now it works very efficiently.

    - (NSInteger)binarySearchForFontSizeForLabel:(UILabel *)label withMinFontSize:(NSInteger)minFontSize withMaxFontSize:(NSInteger)maxFontSize withSize:(CGSize)size {
        // If the sizes are incorrect, return 0, or error, or an assertion.
        if (maxFontSize < minFontSize) {
            return 0;
        }
    
        // Find the middle
        NSInteger fontSize = (minFontSize + maxFontSize) / 2;
        // Create the font
        UIFont *font = [UIFont fontWithName:label.font.fontName size:fontSize];
        // Create a constraint size with max height
        CGSize constraintSize = CGSizeMake(size.width, MAXFLOAT);
        // Find label size for current font size
        CGRect rect = [label.text boundingRectWithSize:constraintSize
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                            attributes:@{NSFontAttributeName : font}
                                               context:nil];
        CGSize labelSize = rect.size;
    
        // EDIT:  The next block is modified from the original answer posted in SO to consider the width in the decision. This works much better for certain labels that are too thin and were giving bad results.
        if (labelSize.height >= (size.height + 10) && labelSize.width >= (size.width + 10) && labelSize.height <= (size.height) && labelSize.width <= (size.width)) {
            return fontSize;
        } else if (labelSize.height > size.height || labelSize.width > size.width) {
            return [self binarySearchForFontSizeForLabel:label withMinFontSize:minFontSize withMaxFontSize:fontSize - 1 withSize:size];
        } else {
            return [self binarySearchForFontSizeForLabel:label withMinFontSize:fontSize + 1 withMaxFontSize:maxFontSize withSize:size];
        }
    }
    
    - (void)sizeBinaryLabel:(UILabel *)label toRect:(CGRect)labelRect {
    
        // Set the frame of the label to the targeted rectangle
        label.frame = labelRect;
    
        // Try all font sizes from largest to smallest font
        int maxFontSize = 300;
        int minFontSize = 5;
    
        NSInteger size = [self binarySearchForFontSizeForLabel:label withMinFontSize:minFontSize withMaxFontSize:maxFontSize withSize:label.frame.size];
    
        label.font = [UIFont fontWithName:label.font.fontName size:size];
    
    }
    

    Credit goes also to https://gist.github.com/988219

提交回复
热议问题