2012-04-13 57 views
2

我知道UIFont和CTFont是不同的東西,但我可以讓它工作。iPhone iOS UIFont轉換爲CTFontRef會導致尺寸錯位

我想生成一個PDF並使用UIView作爲模板,但是爲了繪製可編輯的PDF,我需要在特定的框架中有一個CTFontRef呈現本身。以下是我在PDF上下文中繪製UILabel的方法。 該方法使用UILabel作爲字體名稱,字體大小和位置的模板,而CTFontRef將字符呈現爲PDF。

該方法的工作原理,但有怪癖。

我注意到下面的代碼可能無法在足夠大的框架中渲染以適合使用UIFont書寫的文本。例如,我有一個適合某種字體的80x21 UILabel。如果我嘗試使用CTFontRef呈現該字體,則會得到一個空白區域,除非將標籤的高度增加爲80x30。簡而言之,CTFontRef不會渲染不會水平或垂直剪切幀的文本。

此外,我注意到一些字體有不同的寬度,所以適合20個字符的UIFont的80x21標籤可能只適合15個字符的CTFontRef。我的猜測是這是因爲CTFontRef不會截斷文本,並且不會渲染從框架向任何方向伸出的單詞。

幾個問題: 什麼可能導致我的字體大小不一致?我是否需要複製一些其他財產? 有沒有辦法讓CTFontRef在標籤的末尾截斷長單詞?

//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); 
} 

UPDATE:

我重構代碼,並在用這種方法現在,生產全功能的PDF文本。

+(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]; 
    } 

回答

3

1)您不能混用通過UIKitCoreText繪製文本繪製文本。這在Apple文檔中提到(請參閱Text, Web and Editing Programming for iOS in the section "Core Text and the UIKit Framework")。 (看起來正在發生的事情是,UIKit做了一些四捨五入,並採取一些快捷方式來提高性能,也不會默認使用字距。)

2)不,你不錯過一些屬性。

3)CoreText沒有提供截斷文本的簡單方法,你必須編寫自己的代碼來完成它。

+0

非常感謝,你的回答幫助我解決了這兩個問題! – 2012-04-16 19:33:20

相關問題