【问题标题】:How to resize text to label size?如何将文本大小调整为标签大小?
【发布时间】:2014-01-06 11:10:46
【问题描述】:

我想拉伸 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";

【问题讨论】:

  • 您的意思是要真正拉伸文本还是要根据标签大小调整字体大小?
  • 另一个问题在理论上是合理的,因此它表明您有一些计算错误。显示您针对指定输入看到的问题的代码和屏幕截图。
  • 我真的很想拉伸文本。
  • 我添加了结果截图和标签代码。我使用 CustomUILabel 子类化 UILabel。

标签: ios objective-c uilabel


【解决方案1】:

您的问题归结为计算渲染文本的确切边界框。当您拥有此框时,您可以调整 CTM 以使文本填充所需的区域。

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

  1. 字体度量是一个相当复杂的话题。渲染的字符(字形)有多个边界框,具体取决于意图。
  2. 在字体中,字形通常使用贝塞尔曲线表示,这使得计算精确的边界框变得困难。
  3. 属性可能会以不可预见的方式影响图形外观。例如,AppKit/UIKit 知道一个可以扩展字体渲染像素区域的阴影属性。

还有更多问题,但我列出的问题可能足以表明准确用渲染文本填充框的任务并不容易。

也许还有另一种方式来做你想做的事。

【讨论】:

  • 谢谢。我希望也许有一个解决方案,但我开始相信没有解决方案:)(至少我无法弄清楚)。我会尝试寻找其他解决方案。
猜你喜欢
  • 2012-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 2011-08-10
相关资源
最近更新 更多