首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iPhone iOS UIFont转换为CTFontRef会导致大小失调

iPhone iOS UIFont转换为CTFontRef会导致大小失调
EN

Stack Overflow用户
提问于 2012-04-13 19:05:07
回答 1查看 3.5K关注 0票数 2

我知道UIFont和CTFont是不同的东西,但我能够让它发挥作用。

我试图生成一个PDF并使用一个UIView作为模板,但是要绘制可编辑的PDF,我需要在一个特定的框架中呈现一个CTFontRef。下面是我在PDF上下文中绘制UILabel的方法。方法使用UILabel作为字体名称、字体大小和位置的模板,而CTFontRef则将字符呈现为PDF格式。

这种方法行得通,但也有怪癖。

我注意到下面的代码可能无法在一个大到适合用UIFont编写的文本的框架中呈现。例如,我有一个符合特定字体的80x21 UILabel。如果我尝试用CTFontRef渲染这个字体,我会得到一个空白,除非我增加标签的高度,比如80x30。简单地说,CTFontRef不会呈现没有水平或垂直剪辑框的文本。

另外,我注意到有些字体的宽度不同,所以一个适合UIFont 20个字符的80x21标签可能只适合15个字符的CTFontRef。我的猜测是,这是因为CTFontRef不截断文本,只是不呈现从框架的任何方向突出的单词。

几个问题:,是什么导致我的字体大小不对齐?我需要复制其他财产吗?是否有一种方法可以要求CTFontRef截断标签末尾的长单词?

代码语言:javascript
复制
//xOriginOffset, yOriginOffset is the X of the origin of the container view that holds the label.

+(void)drawTextLabel:(UILabel*)label WithXOriginOffset:(int)xOriginOffset YOffset:(int)yOriginOffset
{

    NSString* textToDraw = label.text;
    CFStringRef stringRef = (__bridge CFStringRef)textToDraw;

    UIFont* uiFont = label.font;


    // Prepare font

   CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)uiFont.fontName, uiFont.pointSize, NULL);

    // Create an attributed string
    CFStringRef keys[] = { kCTFontAttributeName,kCTForegroundColorAttributeName };
    CFTypeRef values[] = { font,[[UIColor redColor]CGColor] };
    CFDictionaryRef attr = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values,
                                              sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    // Prepare the text using a Core Text Framesetter
    CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, stringRef, attr);

    NSAssert(currentText!=nil,@"current text is nil!");
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);

    //account for the view's superview
    CGRect frameRect = CGRectMake(xOriginOffset+label.frame.origin.x,
                                  yOriginOffset+label.frame.origin.y,
                                  label.frame.size.width,
                                  label.frame.size.height);


    CGMutablePathRef framePath = CGPathCreateMutable();
    CGPathAddRect(framePath, NULL, frameRect);

    // Get the frame that will do the rendering.
    CFRange currentRange = CFRangeMake(0, 0);
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
    CGPathRelease(framePath);

    // Get the graphics context.
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

     NSAssert(currentContext!=nil,@"currentContext is nil!");


    // Draw the frame.
    CTFrameDraw(frameRef, currentContext);

    CFRelease(frameRef);
    CFRelease(stringRef);
    CFRelease(framesetter);
}

更新:

我重构了代码,现在正在使用这个方法来生成功能完整的PDF文本。

代码语言:javascript
复制
+(void)drawTextLabel:(UILabel*)label WithXOriginOffset:(int)xOriginOffset YOffset:(int)yOriginOffset
{

    NSString* textToDraw = label.text;

    UIFont* uiFont = label.font;
        // Prepare font
    CGRect frameRect = CGRectMake(xOriginOffset+label.frame.origin.x,
                                  yOriginOffset+label.frame.origin.y,
                                  label.frame.size.width,
                                  label.frame.size.height);

    [textToDraw drawInRect:frameRect withFont:uiFont lineBreakMode:UILineBreakModeTailTruncation];
  }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-13 21:34:44

1)不能将UIKit绘制的文本与CoreText绘制的文本混合。苹果文档中提到了这一点(参见iOS的文本、网络和编辑编程在“核心文本和UIKit框架”一节中)。(看起来UIKit做了一些四舍五入,并采取了一些捷径来提高性能,而且默认情况下也不做角化。)

2)不,你没有丢失一些财产。

3) CoreText没有提供一种简单的截断文本的方法,您必须编写自己的代码才能做到这一点。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10146823

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档