UILabel autoshrink and use 2 lines if necessary

徘徊边缘 提交于 2019-12-25 04:42:31

问题


I've got a UILabel that I would like to first shrink the text to fit a single line if possible. If that doesn't work I would like it to use at the most two lines. Is this possible?

Currently with the settings I have it does this:

Here is my layout

If I change the lines setting to 1 line the text does shrink.


回答1:


I came up with a solution.

  1. Set "Lines" to 2
  2. Set "Line Breaks" to "Truncate Tail"
  3. Set "Autoshrink" to "Minimum Font Scale" and set the value to 0.1 (or however small you want it to be)
  4. (Optional) Check "Tighten Letter Spacing"

The next part was in code. I subclassed UILabel and came up with this.

#import <UIKit/UIKit.h>

@interface HMFMultiLineAutoShrinkLabel : UILabel

- (void)autoShrink;

@end

.

#import "HMFMultiLineAutoShrinkLabel.h"

@interface HMFMultiLineAutoShrinkLabel ()

@property (readonly, nonatomic) UIFont* originalFont;

@end

@implementation HMFMultiLineAutoShrinkLabel

@synthesize originalFont = _originalFont;

- (UIFont*)originalFont { return _originalFont ? _originalFont : (_originalFont = self.font); }

- (void)autoShrink {
    UIFont* font = self.originalFont;
    CGSize frameSize = self.frame.size;

    CGFloat testFontSize = _originalFont.pointSize;
    for (; testFontSize >= self.minimumScaleFactor * self.font.pointSize; testFontSize -= 0.5)
    {
        CGSize constraintSize = CGSizeMake(frameSize.width, MAXFLOAT);
        CGRect testRect = [self.text boundingRectWithSize:constraintSize
                                                       options:NSStringDrawingUsesLineFragmentOrigin
                                                    attributes:@{NSFontAttributeName:font}
                                                       context:nil];
        CGSize testFrameSize = testRect.size;
        // the ratio of testFontSize to original font-size sort of accounts for number of lines
        if (testFrameSize.height <= frameSize.height * (testFontSize/_originalFont.pointSize))
            break;
    }

    self.font = font;
    [self setNeedsLayout];
}

@end

Then whenver you change the text of the label just call autoShrink and it will be correctly sized and will go two two lines only if necessary.

I got most of this code from john.k.doe's answer from this question (https://stackoverflow.com/a/11788385/758083)



来源:https://stackoverflow.com/questions/30893366/uilabel-autoshrink-and-use-2-lines-if-necessary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!