如何在iOS中渲染拉伸文本? [英] How to render stretched text in iOS?
问题描述
- 这与改变字体大小并不相同。
- 将其渲染为位图,然后缩放它是不是一个选项(它看起来很可怕)
- 矢量图形是做到这一点的方式
解决方案
我想出了以下这些似乎适用于我的目的。代码绘制一行文本缩放来填充边界。子类 UIView
并替换 drawRect
,如下所示。
- (void)drawRect:(CGRect)rect
{
[self drawScaledString:@Abcde ];
$ b - (void)drawScaledString:(NSString *)string
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context,CGAffineTransformIdentity);
NSAttributedString * attrString = [self generateAttributedString:string]; (CFMutableAttributedStringRef)attrString,CFRangeMake(0,string.length),
kCTForegroundColorAttributeName,[UIColor redColor] .CGColor);
CFAttributedStringSetAttribute
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attrString);
// CTLineGetTypographicBounds不会给出正确的值,
//使用GetImageBounds而不是
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);
$ b - (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;
$ b 示例:
CGRect rect = CGRectMake(0,0,50,280);
MyCTLabel * label = [[MyCTLabel alloc] initWithFrame:rect];
label.backgroundColor = [UIColor whiteColor];
[self addSubview:label];
解决方案您可以尝试CoreText。得到一个 CTFramesetter
,计算它的矩形,然后计算将该矩形压缩到所需边界所需的仿射变换,并将其设置为CTM。然后当你画出文字时,应该以完整的质量适当地拉伸。
Given a rectangular area, I want to render some text using a specific font and have the rendered text fill out the rectangle. As in the image below:
- This is not the same as just changing font size
- Rendering it as a bitmap and then scale it is not an option (it looks horrible)
- Vector graphics is the way to do it
Solution
I came up with the following which seems to work for my purposes. The code draws a single line of text scaling to fill the bounds. Subclass UIView
and replace drawRect
as follows.
- (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;
}
Example usage:
CGRect rect = CGRectMake(0, 0, 50, 280);
MyCTLabel *label = [[MyCTLabel alloc] initWithFrame:rect];
label.backgroundColor = [UIColor whiteColor];
[self addSubview:label];
解决方案 You could try CoreText. Get a CTFramesetter
, calculate its rect, then calculate the affine transform necessary to compress that rect into the bounds you want and set that as the CTM. Then when you draw the text, it should stretch it appropriately at full quality.
这篇关于如何在iOS中渲染拉伸文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!