【问题标题】:Core Text / NSStringDrawing - CFAttributedStringRef / NSAttributedString - changing font sizeCore Text / NSStringDrawing - CFAttributedStringRef / NSAttributedString - 改变字体大小
【发布时间】:2013-11-08 04:11:13
【问题描述】:

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

我猜我们也可以

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

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

【问题讨论】:

    标签: iphone objective-c ipad core-text


    【解决方案1】:

    我已经让它与以下代码一起工作。但是,如果未将属性字符串中的某些文本设置为字体属性,则它不会被更新。所以我不得不用字体属性封装所有东西。

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

    【讨论】:

      【解决方案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
      

      愉快的编码

      【讨论】:

      • “这在 Mac OS 和 iOS 上都可以正常工作” UIFont 在 OS X 中可用吗?
      • 另外,-[UIFont fontWithSize:] 有什么问题?
      • 对,换成NSFont就好了。我现在不记得这个问题到底是什么,但我认为它试图以一种非常错误的方式变得聪明。如果我没记错的话,我得到了错误的字体系列!相当令人震惊。我在某处写过,我看看能不能找到。
      • 好的,所以我在我的笔记中找不到它,但事实证明其他人也遇到了同样的问题。见github.com/djibouti33/UIFontBug/blob/master/htmlLabelTest/…stackoverflow.com/questions/31041318/…
      • 感谢您跟踪!在此处提供解释链接会很有帮助。
      【解决方案3】:

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

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

      【讨论】:

      • 我不太确定哪里最好实现 CGAffineTransformMakeScale()。我尝试在drawrect中这样做,但后来它只是应用于所有奇怪的字形,因为它们具有相同的位置。
      • 另外,我真的很想在实际绘图之前知道尺寸、留下的文字等。
      • 你好。请看看我的尝试。我是否遗漏了什么,或者在这样做时我应该考虑什么?
      • 我认为您可以使用默认系统字体(和字体大小)作为那些没有字体属性的格式化段的基础。只是一个把戏。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-19
      • 2019-09-29
      • 1970-01-01
      • 2015-06-19
      • 1970-01-01
      相关资源
      最近更新 更多