菜鸟教程小白 发表于 2022-12-13 13:14:10

iPhone iOS UIFont 转换为 CTFontRef 导致大小不对齐


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

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

<p>该方法有效,但有一些怪癖。</p>

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

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

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

<pre><code>//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,[CGColor] };
    CFDictionaryRef attr = CFDictionaryCreate(NULL, (const void **)&amp;keys, (const void **)&amp;values,
                                              sizeof(keys) / sizeof(keys), &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);

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

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

    //account for the view&#39;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,@&#34;currentContext is nil!&#34;);


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

    CFRelease(frameRef);
    CFRelease(stringRef);
    CFRelease(framesetter);
}
</code></pre>

<p>更新:</p>

<p>我重构了代码,现在正在使用这种方法来生成功能齐全的 PDF 文本。 </p>

<pre><code>+(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);

    ;
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>1) 您不能将 <code>UIKit</code> 绘制的文本与 <code>CoreText</code> 绘制的文本混合。这在 Apple 文档中有所提及(参见 <a href="http://developer.apple.com/library/ios/#DOCUMENTATION/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/CustomTextProcessing/CustomTextProcessing.html" rel="noreferrer noopener nofollow">Text, Web and Editing Programming for iOS in the section &#34;Core Text and the UIKit Framework&#34; </a>)。 (似乎正在发生的事情是 UIKit 会进行一些舍入并采取一些捷径来提高性能,并且默认情况下也不进行字距调整。)</p>

<p>2) 不,您没有遗漏某些属性。</p>

<p>3) CoreText 没有提供截断文本的简单方法,您必须编写自己的代码才能做到这一点。</p></p>
                                   
                                                <p style="font-size: 20px;">关于iPhone iOS UIFont 转换为 CTFontRef 导致大小不对齐,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/10146823/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/10146823/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: iPhone iOS UIFont 转换为 CTFontRef 导致大小不对齐