如何在Core Text中添加属性范围?

时间:2016-06-02 13:40:34

标签: ios objective-c core-text

我有兴趣在CoreText中创建一个尽可能多地表现UILabel行为的方法。因此,如果我希望实现类似的目标:

   UIFont *font1 = [UIFont fontWithName:kMyriadProSemiBold size:15];
NSDictionary *arialDict = [NSDictionary dictionaryWithObject: font1 forKey:NSFontAttributeName];
NSMutableAttributedString *aAttrString1 = [[NSMutableAttributedString alloc] initWithString:@"My" attributes: arialDict];

UIFont *font2 = [UIFont fontWithName:kMyriadProRegular size:15];
NSDictionary *arialDict2 = [NSDictionary dictionaryWithObject: font2 forKey:NSFontAttributeName];
NSMutableAttributedString *aAttrString2 = [[NSMutableAttributedString alloc] initWithString:@"Profile" attributes: arialDict2];

[aAttrString1 appendAttributedString:aAttrString2];

但是使用Core Text。

目前我正在使用下一个方法:

+ (void)drawText:(NSString *)textToDraw
         inFrame:(CGRect)frameRect
        withFont:(UIFont *)originalFont
       textColor:(UIColor *)textColor
       alignment:(PDFTextAlignment)alignment{

    if (!textToDraw) {
        // If nil, give it an empty value to draw
        textToDraw = @"";
    }


    // Prepare font
    CTFontRef font = [PDFManager ctFontRefFromUIFont:originalFont];
    CGColorRef color = textColor.CGColor;

    // Paragraph
    CTTextAlignment ctAlignment;
    switch (alignment) {
        case PDFTextAlignmentLeft:
            ctAlignment = kCTTextAlignmentLeft;
            break;
        case PDFTextAlignmentCenter:
            ctAlignment = kCTTextAlignmentCenter;
            break;
        case PDFTextAlignmentRight:
            ctAlignment = kCTTextAlignmentRight;
            break;
        case PDFTextAlignmentJustified:
            ctAlignment = kCTTextAlignmentJustified;
            break;
        default:
            ctAlignment = kCTTextAlignmentLeft;
            break;
    }

    CTParagraphStyleSetting settings[] = {
        {kCTParagraphStyleSpecifierAlignment, sizeof(ctAlignment), &ctAlignment},
    };

    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));

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

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

    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);


    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();

    // Put the text matrix into a known state. This ensures
    // that no old scaling factors are left in place.
    CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);

    // Core Text draws from the bottom-left corner up, so flip
    // the current transform prior to drawing.
    // Modify this to take into consideration the origin.
    CGContextTranslateCTM(currentContext, 0, frameRect.origin.y*2);
    CGContextScaleCTM(currentContext, 1.0, -1.0);

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

    // Add these two lines to reverse the earlier transformation.
    CGContextScaleCTM(currentContext, 1.0, -1.0);
    CGContextTranslateCTM(currentContext, 0, (-1)*frameRect.origin.y*2);

    //Confirm that everything is released that needs to be!
    CFRelease(frameRef);
    CFRelease(stringRef);
    CFRelease(framesetter);
    CFRelease(font);
    CFRelease(paragraphStyle);
}

我需要更新CFDictionaryRef attr才能接受新属性吗?

1 个答案:

答案 0 :(得分:0)

我最终实际使用NSAttributedString作为fallows并将方法从上面转换为:

+ (void)drawAttributedText:(NSAttributedString *)textToDraw
                   inFrame:(CGRect)frameRect
                 alignment:(PDFTextAlignment)alignment{

    // Paragraph
    CTTextAlignment ctAlignment;
    switch (alignment) {
        case PDFTextAlignmentLeft:
            ctAlignment = kCTTextAlignmentLeft;
            break;
        case PDFTextAlignmentCenter:
            ctAlignment = kCTTextAlignmentCenter;
            break;
        case PDFTextAlignmentRight:
            ctAlignment = kCTTextAlignmentRight;
            break;
        case PDFTextAlignmentJustified:
            ctAlignment = kCTTextAlignmentJustified;
            break;
        default:
            ctAlignment = kCTTextAlignmentLeft;
            break;
    }

    CTParagraphStyleSetting settings[] = {
        {kCTParagraphStyleSpecifierAlignment, sizeof(ctAlignment), &ctAlignment},
    };

    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));

    CFAttributedStringRef currentText = (__bridge CFAttributedStringRef)textToDraw;

    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);

    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();

    // Put the text matrix into a known state. This ensures
    // that no old scaling factors are left in place.
    CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);

    // Core Text draws from the bottom-left corner up, so flip
    // the current transform prior to drawing.
    // Modify this to take into consideration the origin.
    CGContextTranslateCTM(currentContext, 0, frameRect.origin.y*2);
    CGContextScaleCTM(currentContext, 1.0, -1.0);

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

    // Add these two lines to reverse the earlier transformation.
    CGContextScaleCTM(currentContext, 1.0, -1.0);
    CGContextTranslateCTM(currentContext, 0, (-1)*frameRect.origin.y*2);

    //Confirm that everything is released that needs to be!
    CFRelease(frameRef);
    CFRelease(framesetter);
    CFRelease(paragraphStyle);

}

+ (NSMutableAttributedString *)getAttributedString:(NSString *)str
                                          withFont:(UIFont *)font
                                          andColor:(UIColor *)fontColor{
    NSDictionary *arialDict = [NSDictionary dictionaryWithObject: font forKey:NSFontAttributeName];
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:str attributes: arialDict];
    return attrString;
}

以及使用它的方式是:

+ (void)drawPDFTitleUsingString:(NSString *)passedTitle{



    NSMutableAttributedString *attStr1 = [self getAttributedString:NSLocalizedString(@"Normal part of the string, ", nil)
                                                       withFont:FONT_CLEAR_SANS_REGULAR(18)
                                                       andColor:[UIColor blackColor]];

    NSMutableAttributedString *attStr2 = [self getAttributedString:NSLocalizedString(@"bold part of the string", nil)
                                                         withFont:FONT_CLEAR_SANS_BOLD(18)
                                                         andColor:[UIColor blackColor]];

    [attStr1 appendAttributedString:attStr2];

    [self drawAttributedText:attStr1
                     inFrame:CGRectMake(PDFTableXPosition, 15 + 55,  PDFTableWidth, 42)
                   alignment:PDFTextAlignmentLeft];

}