Core Text / NSStringDrawing - CFAttributedStringRef / NSAttributedString - 更改字体大小

发布于 2024-09-09 11:11:27 字数 106 浏览 8 评论 0原文

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

我猜我们可以

A) 更新属性字符串中所有字体的 pointSize

B) 通过一些变换绘制属性字符串

Case: The attributed string is already created. How can the size of the string be altered?

I'm guessing we could either

A) Update pointSize for all fonts in the attributed string

B) Draw the attributed string with some transform

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乱了心跳 2024-09-16 11:11:27

我已经用下面的代码让它工作了。但有一个问题是,如果属性字符串中的某些文本尚未设置字体属性,则它将不会更新。所以我必须用字体属性封装所有内容。

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

 }

I've got it working with the following code. One miss though is if some text in the attributedstring has not been set a font-attribute it will not be updated. So i had to encapsulate everything with 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); 

 }
余生一个溪 2024-09-16 11:11:27

这在 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

快乐编码

This works fine on both Mac OS and 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

Happy coding

您的好友蓝忘机已上羡 2024-09-16 11:11:27

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

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

I believe parsing is the only way. Attributed string can have quite complex format, it's your job to increase the font size.

However, if you need this trick for rendering, you can avoid string parsing - use a scale transform to increase the text size.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文