如何将文本大小调整为标签大小?

时间:2014-01-06 11:10:47

标签: ios objective-c uilabel

我想在UILabel中拉伸文本,以便恰好适合标签(宽度和高度)。我不想以任何方式调整UILabel的大小。

到目前为止,我使用了这个:How to render stretched text in iOS?,但是文本没有伸展100%(有时它会超出边界,有时会在边距上留下间距)。

还有其他(最好更容易)的方法吗?

这就是我所说的:http://i.imgur.com/AMvfhsA.png。我得到左边的间距,文字超出了右边和底边的边界。

这是自定义标签类:

#import "CustomUILabel.h"

@implementation CustomUILabel

- (id)initWithFrame:(CGRect)frame text:(NSString*)text
{
    self = [super initWithFrame:frame];
    if (self) {
        self.edgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
        self.text = text;
    }
    return self;
}

- (void)drawTextInRect:(CGRect)rect {
    [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)];
}

- (void)drawRect:(CGRect)rect
{
    [self drawScaledString:self.text];
}

- (void)drawScaledString:(NSString *)string
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

    NSAttributedString *attrString = [self generateAttributedString:string];

    CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attrString, CFRangeMake(0, string.length),
                                   kCTForegroundColorAttributeName, self.textColor.CGColor);

    CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef) attrString);

    // CTLineGetTypographicBounds doesn't give correct values,
    // using GetImageBounds instead
    CGRect imageBounds = CTLineGetImageBounds(line, context);
    CGFloat width = imageBounds.size.width;
    CGFloat height = imageBounds.size.height;

    CGFloat padding = 0;

    width += padding;
    height += padding;

    float sx = self.bounds.size.width / width;
    float sy = self.bounds.size.height / height;

    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

    CGContextTranslateCTM(context, 1, self.bounds.size.height);
    CGContextScaleCTM(context, 1, -1);
    CGContextScaleCTM(context, sx, sy);

    CGContextSetTextPosition(context, -imageBounds.origin.x + padding/2, -imageBounds.origin.y + padding/2);

    CTLineDraw(line, context);
    CFRelease(line);
}

- (NSAttributedString *)generateAttributedString:(NSString *)string
{

    CTFontRef helv = CTFontCreateWithName(CFSTR("Helvetica-Bold"),20, NULL);
    CGColorRef color = [UIColor blackColor].CGColor;

    NSDictionary *attributesDict = [NSDictionary dictionaryWithObjectsAndKeys:
                                    (__bridge id)helv, (NSString *)kCTFontAttributeName,
                                    color, (NSString *)kCTForegroundColorAttributeName,
                                    nil];

    NSAttributedString *attrString = [[NSMutableAttributedString alloc]
                                       initWithString:string
                                       attributes:attributesDict];

    return attrString;
}

@end

这就是我使用它的方式(我从故事板中添加了标签):

@property (weak, nonatomic) IBOutlet CustomUILabel *label;

...

self.label.backgroundColor = [UIColor redColor];
self.label.text = @"OOOOO";

1 个答案:

答案 0 :(得分:0)

您所要求的归结为计算渲染文本的精确边界框。如果有此框,则可以调整CTM以使文本填充所需区域。

然而:似乎没有一种简单的方法可以做到这一点。很多问题都会导致这个问题:

  1. 字体指标是一个非常复杂的主题。渲染字符(字形)根据意图有几个边界框。
  2. 在字体中,字形通常使用贝塞尔曲线表示,这使得计算精确的边界框变得困难。
  3. 属性可能以不可预见的方式影响图形外观。例如,AppKit / UIKit知道一个可以扩展字体渲染像素的区域的阴影属性。
  4. 还有更多问题,但我列出的问题可能足以证明完全填充带有渲染文本的框的任务并不那么容易。

    也许还有另一种方法可以做你想到的事情。