核心文本/ NSStringDrawing - CFAttributedStringRef / NSAttributedString - 更改字体大小

时间:2010-07-13 15:02:17

标签: iphone objective-c ipad core-text

案例:已创建属性字符串。如何改变字符串的大小?

我猜我们可以

A)更新属性字符串

中所有字体的pointSize

B)用一些变换

绘制属性字符串

3 个答案:

答案 0 :(得分:2)

我已经使用以下代码了。但遗漏的是,如果尚未设置attributesstring中的某些文本,则不会更新font-attribute。所以我不得不用font-attributes封装所有内容。

- (void)recalculateSizeChangeInAttributedString {

    if(self.attributedStringOriginal == nil) {
        self.attributedStringOriginal = [self.attributedString copy];
    }

    CFMutableAttributedStringRef tempString = CFAttributedStringCreateMutableCopy(CFAllocatorGetDefault(), self.attributedStringOriginal.length, (CFMutableAttributedStringRef)self.attributedStringOriginal);

    int lastIndex = 0;
    int limit = CFAttributedStringGetLength(tempString);
    for (int index = 0; index < limit;) {

        CFRange inRange = CFRangeMake(0, limit - index);
        CFRange longestEffective;
        CTFontRef font = (CTFontRef)CFAttributedStringGetAttribute(tempString, index, kCTFontAttributeName, &longestEffective);

        if(font != nil) {

            // log for testing
            NSLog(@"index: %i, range: %i - %i, longest: %i - %i, attribute: %@", 
                  index, inRange.location, 
                  inRange.location + inRange.length, 
                  longestEffective.location, longestEffective.location + longestEffective.length, 
                  @"..." 
                  );


            // alter the font and set the altered font/attribute
            int rangeEnd = longestEffective.length != 0 ? longestEffective.length : 1;
            CTFontRef modifiedFont = CTFontCreateCopyWithAttributes(font, CTFontGetSize((CTFontRef)font) * sizeFactor, NULL, NULL); 
            CFAttributedStringSetAttribute(tempString, CFRangeMake(index, rangeEnd), kCTFontAttributeName, modifiedFont); 
            CFRelease(modifiedFont);

        }

        // make next loop continue where current attribute ended
        index += longestEffective.length; 

        if(index == lastIndex)
            index ++;
        lastIndex = index;

    }

    self.attributedString = (NSMutableAttributedString *)tempString;

    CFRelease(tempString); 

 }

答案 1 :(得分:2)

这适用于Mac OS和iOS

@implementation NSAttributedString (Scale)

- (NSAttributedString *)attributedStringWithScale:(double)scale
{
    if(scale == 1.0)
    {
        return self;
    }

    NSMutableAttributedString *copy = [self mutableCopy];
    [copy beginEditing];

    NSRange fullRange = NSMakeRange(0, copy.length);

    [self enumerateAttribute:NSFontAttributeName inRange:fullRange options:0 usingBlock:^(UIFont *oldFont, NSRange range, BOOL *stop) {
        double currentFontSize = oldFont.pointSize;
        double newFontSize = currentFontSize * scale;

        // don't trust -[UIFont fontWithSize:]
        UIFont *scaledFont = [UIFont fontWithName:oldFont.fontName size:newFontSize];

        [copy removeAttribute:NSFontAttributeName range:range];
        [copy addAttribute:NSFontAttributeName value:scaledFont range:range];
    }];

    [self enumerateAttribute:NSParagraphStyleAttributeName inRange:fullRange options:0 usingBlock:^(NSParagraphStyle *oldParagraphStyle, NSRange range, BOOL *stop) {

        NSMutableParagraphStyle *newParagraphStyle = [oldParagraphStyle mutableCopy];
        newParagraphStyle.lineSpacing *= scale;
        newParagraphStyle.paragraphSpacing *= scale;
        newParagraphStyle.firstLineHeadIndent *= scale;
        newParagraphStyle.headIndent *= scale;
        newParagraphStyle.tailIndent *= scale;
        newParagraphStyle.minimumLineHeight *= scale;
        newParagraphStyle.maximumLineHeight *= scale;
        newParagraphStyle.paragraphSpacing *= scale;
        newParagraphStyle.paragraphSpacingBefore *= scale;

        [copy removeAttribute:NSParagraphStyleAttributeName range:range];
        [copy addAttribute:NSParagraphStyleAttributeName value:newParagraphStyle range:range];
    }];

    [copy endEditing];
    return copy;
}

@end

快乐编码

答案 2 :(得分:0)

我相信解析是唯一的方法。归因字符串可以具有相当复杂的格式,增加字体大小是你的工作。

但是,如果你需要这个技巧来渲染,你可以避免字符串解析 - 使用缩放变换来增加文本大小。