如何在iOS中渲染拉伸文本?

时间:2011-03-09 18:31:49

标签: iphone ios fonts core-graphics uilabel

给定一个矩形区域,我想使用特定字体渲染一些文本,并使渲染文本填充矩形。如下图所示:

enter image description here

  1. 这与仅更改字体大小不同
  2. 将其渲染为位图,然后缩放它不是一个选项(看起来很糟糕)
  3. 矢量图形就是这样做的方式
  4. 解决方案

    我想出了以下似乎适用于我的目的。代码绘制一行文本缩放以填充边界。子类UIView并替换drawRect,如下所示。

    - (void)drawRect:(CGRect)rect 
    {
        [self drawScaledString:@"Abcde"]; 
    }
    
    - (void)drawScaledString:(NSString *)string
    {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    
        NSAttributedString *attrString = [self generateAttributedString:string];
    
        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attrString, CFRangeMake(0, string.length), 
                                       kCTForegroundColorAttributeName, [UIColor redColor].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:
                                        (id)helv, (NSString *)kCTFontAttributeName,
                                        color, (NSString *)kCTForegroundColorAttributeName,
                                        nil];
    
        NSAttributedString *attrString = [[[NSMutableAttributedString alloc]
                                       initWithString:string
                                            attributes:attributesDict] autorelease];
    
        return attrString;
    }
    

    使用示例:

    CGRect rect = CGRectMake(0, 0, 50, 280);
    MyCTLabel *label = [[MyCTLabel alloc] initWithFrame:rect];
    label.backgroundColor = [UIColor whiteColor]; 
    [self addSubview:label];
    

3 个答案:

答案 0 :(得分:5)

您可以设置UILabel变换属性并缩放宽度:

[myLabel sizeToFit];
myLabel.transform = CGAffineTransformMakeScale(0.5, 1.0);

答案 1 :(得分:2)

您可以尝试使用CoreText。获取CTFramesetter,计算其rect,然后计算将该rect压缩到所需边界所需的仿射变换,并将其设置为CTM。然后,当你绘制文本时,它应该以完全的质量适当地拉伸它。

答案 2 :(得分:0)

您也可以尝试使用UILabel @property(nonatomic) BOOL adjustsFontSizeToFitWidth@property minimumFontSize

最初,您可以为font属性设置更高的值,并使用最小字体值初始化minimumFontSize