You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改NSAttributedString全局字体大小且保留其他原有属性?

NSAttributedString 统一修改字号且保留原有属性的实现方案

核心逻辑:遍历富文本内所有配置了字体属性的区间,基于原字体的描述符生成仅字号变更的新字体替换原有字体属性,其余所有属性(字重、颜色、下划线、段落样式、字间距、链接等)完全保留,不会被篡改。


代码实现

Swift 实现

给NSAttributedString增加扩展方法:

import UIKit

extension NSAttributedString {
    func resizingFont(to targetSize: CGFloat) -> NSAttributedString {
        let mutableContent = NSMutableAttributedString(attributedString: self)
        let fullRange = NSRange(location: 0, length: mutableContent.length)
        // 遍历所有字体属性的有效区间
        mutableContent.enumerateAttribute(
            .font,
            in: fullRange,
            options: .longestEffectiveRangeNotRequired
        ) { originalFont, range, _ in
            guard let font = originalFont as? UIFont else { return }
            // 保留原字体全部特征(字重、字体族、斜体/粗体标记等),仅替换字号
            let newFont = UIFont(descriptor: font.fontDescriptor, size: targetSize)
            mutableContent.addAttribute(.font, value: newFont, range: range)
        }
        return mutableContent
    }
}

需要设置字号为20时直接调用即可:

let finalAttrStr = yourOriginalAttrStr.resizingFont(to: 20)

Objective-C 实现

#import <UIKit/UIKit.h>

@interface NSAttributedString (AZFontResize)
- (NSAttributedString *)az_resizeFontToSize:(CGFloat)targetSize;
@end

@implementation NSAttributedString (AZFontResize)
- (NSAttributedString *)az_resizeFontToSize:(CGFloat)targetSize {
    NSMutableAttributedString *mutableContent = [[NSMutableAttributedString alloc] initWithAttributedString:self];
    NSRange fullRange = NSMakeRange(0, self.length);
    [mutableContent enumerateAttribute:NSFontAttributeName
                              inRange:fullRange
                              options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
                           usingBlock:^(id value, NSRange range, BOOL *stop) {
        if (![value isKindOfClass:[UIFont class]]) return;
        UIFont *originalFont = (UIFont *)value;
        UIFont *newFont = [UIFont fontWithDescriptor:originalFont.fontDescriptor size:targetSize];
        [mutableContent addAttribute:NSFontAttributeName value:newFont range:range];
    }];
    return [mutableContent copy];
}
@end

macOS 平台适配:将代码中UIFont替换为NSFont即可,逻辑完全通用。


避坑说明

  • 不要直接给富文本全范围调用addAttribute:value:range:设置统一字体,这种写法会覆盖所有子区间原本的字体差异,比如原本的粗体、斜体、自定义字体会全部被重置。
  • 优先使用enumerateAttribute针对字体属性做遍历,不要全量遍历所有属性,避免不必要的性能损耗,也不会误修改其他非字体属性。
  • 基于原字体的fontDescriptor生成新字体是保留原有字体样式的关键,不要直接用UIFont.systemFont(ofSize:)这类方法生成新字体,否则会丢失原字体的特征。

内容的提问来源于stack exchange,提问作者Deepak Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:48:20