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

NSAttributedString动态文本适配:修改系统字号后UILabel不更新问题求解

解决NSAttributedString下UILabel字号不随系统无障碍设置更新的问题

当你用NSAttributedString给UILabel设置attributedText时,adjustsFontForContentSizeCategory = true不会自动生效——这个属性仅对普通的text属性有效。要让富文本字号跟随系统无障碍设置变化,需要手动监听字号更新通知,重新生成富文本。

具体实现步骤:

  • 添加UIContentSizeCategory.didChangeNotification通知监听,捕捉系统字号变化事件
  • 在通知回调中,重新生成包含自适应字体的NSAttributedString并赋值给UILabel
  • 在合适的时机移除监听,避免内存泄漏

代码示例(ViewController中实现):

class YourViewController: UIViewController {
    @IBOutlet weak var customLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 初始化时设置富文本
        updateAttributedText()
        // 注册字号变化通知
        NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryChanged), name: UIContentSizeCategory.didChangeNotification, object: nil)
    }
    
    deinit {
        // 移除通知监听
        NotificationCenter.default.removeObserver(self, name: UIContentSizeCategory.didChangeNotification, object: nil)
    }
    
    @objc private func contentSizeCategoryChanged() {
        // 字号变化时重新生成富文本
        updateAttributedText()
    }
    
    private func updateAttributedText() {
        // 生成适配当前字号类别的字体
        let scaledFont = UIFontMetrics(forTextStyle: .caption2).scaledFont(for: UIFont.systemFont(ofSize: 11))
        // 构建富文本属性
        let attributes: [NSAttributedString.Key: Any] = [
            .font: scaledFont,
            .foregroundColor: UIColor.black
        ]
        // 赋值给Label
        customLabel.attributedText = NSAttributedString(string: "你的富文本内容", attributes: attributes)
    }
}

更优雅的封装:自定义UILabel

如果多个页面需要这个功能,可以封装成自定义Label,内部处理监听逻辑:

class AutoScalingAttributedLabel: UILabel {
    // 定义闭包,用于外部提供富文本生成逻辑
    var attributedTextBuilder: (() -> NSAttributedString?)? {
        didSet {
            refreshAttributedText()
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupNotification()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupNotification()
    }
    
    private func setupNotification() {
        NotificationCenter.default.addObserver(self, selector: #selector(onContentSizeChanged), name: UIContentSizeCategory.didChangeNotification, object: nil)
    }
    
    @objc private func onContentSizeChanged() {
        refreshAttributedText()
    }
    
    private func refreshAttributedText() {
        attributedText = attributedTextBuilder?()
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

// 使用示例
let label = AutoScalingAttributedLabel()
label.attributedTextBuilder = {
    let scaledFont = UIFontMetrics(forTextStyle: .caption2).scaledFont(for: UIFont.systemFont(ofSize: 11))
    return NSAttributedString(string: "自适应富文本内容", attributes: [.font: scaledFont])
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:46:57