OGeek|极客世界-中国程序员成长平台

标题: iPhone iOS UIFont 转换为 CTFontRef 导致大小不对齐 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 13:14
标题: iPhone iOS UIFont 转换为 CTFontRef 导致大小不对齐

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

我正在尝试生成 PDF 并使用 UIView 作为模板,但是要绘制可编辑的 PDF,我需要让 CTFontRef 在某个帧中呈现自身。下面是我在 PDF 上下文中绘制 UILabel 的方法。 该方法使用 UILabel 作为字体名称、字体大小和位置的模板,而 CTFontRef 将字符渲染为 PDF。

该方法有效,但有一些怪癖。

我注意到下面的代码可能无法在一个大到足以容纳使用 UIFont 编写的文本的框架中呈现。例如,我有一个适合某种字体的 80x21 UILabel。如果我尝试使用 CTFontRef 渲染该字体,我会得到一个空格,除非我将标签的高度增加到 80x30。简而言之,CTFontRef 不会渲染没有水平或垂直剪辑框架的文本。

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

几个问题: 什么可能导致我的字体大小不对齐?我需要复制一些其他属性吗? 有没有办法让 CTFontRef 截断标签末尾的长词?

//xOriginOffset, yOriginOffset is the X of the origin of the container view that holds the label.

+(void)drawTextLabelUILabel*)label WithXOriginOffsetint)xOriginOffset YOffsetint)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 文本。

+(void)drawTextLabelUILabel*)label WithXOriginOffsetint)xOriginOffset YOffsetint)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];
  }



Best Answer-推荐答案


1) 您不能将 UIKit 绘制的文本与 CoreText 绘制的文本混合。这在 Apple 文档中有所提及(参见 Text, Web and Editing Programming for iOS in the section "Core Text and the UIKit Framework" )。 (似乎正在发生的事情是 UIKit 会进行一些舍入并采取一些捷径来提高性能,并且默认情况下也不进行字距调整。)

2) 不,您没有遗漏某些属性。

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

关于iPhone iOS UIFont 转换为 CTFontRef 导致大小不对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10146823/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://jike.in/) Powered by Discuz! X3.4