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

如何在@AppStorage中存储Font?实现RawRepresentable及字体家族修改

问题解答

一、为SwiftUI的Font实现RawRepresentable协议

要让Font支持AppStorage,需实现RawRepresentable协议,将字体的家族名和字号序列化为字符串,再从字符串反序列化为Font:

import SwiftUI
import CoreText

extension Font: RawRepresentable {
    public typealias RawValue = String
    
    // 从字符串反序列化为Font
    public init?(rawValue: RawValue) {
        let parts = rawValue.components(separatedBy: ",")
        guard parts.count == 2, let size = Double(parts[1]) else {
            return nil
        }
        let familyName = parts[0]
        self = Font.custom(familyName, size: CGFloat(size))
    }
    
    // 将Font序列化为字符串
    public var rawValue: RawValue {
        guard let ctFont = self as? CTFont else {
            return ""
        }
        let familyName = CTFontCopyFamilyName(ctFont) as String
        let size = CTFontGetSize(ctFont)
        return "\(familyName),\(size)"
    }
}

说明:

  • 借助CoreText的CTFont获取字体核心信息,SwiftUI的Font底层封装了CTFont
  • 序列化格式为"家族名,字号",解析时拆分字符串并验证格式有效性
  • 若序列化失败(如系统内置字体无法转为CTFont),返回空字符串,反序列化时会返回nil

二、仅修改字体家族,保留原有字号

当前代码固定了字号18,要实现只切换字体家族、保留原有字号的效果,可按以下方式修改:

1. 为Font添加扩展获取字号

extension Font {
    // 获取字体的字号(基于CoreText)
    var fontSize: CGFloat? {
        (self as? CTFont).map { CGFloat(CTFontGetSize($0)) }
    }
}

2. 修改FontPicker中的字体选择逻辑

在sheet的SUIFontPicker回调里,提取选中字体的家族名,使用当前的字号(优先自定义字体的字号,其次是环境默认字体的字号,最后 fallback 到18):

.sheet(isPresented: $isFontPickerPresented) {
    SUIFontPicker { fontDescriptor in
        guard let familyName = fontDescriptor.familyName else { return }
        // 确定要使用的字号
        let targetSize = vm.font?.fontSize ?? defaultFont?.fontSize ?? 18
        // 创建仅修改家族的Font
        vm.font = Font.custom(familyName, size: targetSize)
        printDetails()
    }
}

说明:

  • 从UIFontDescriptor中提取familyName,即用户选择的字体家族
  • 优先沿用已保存的自定义字体字号,若没有则使用环境默认字体的字号,确保字号与之前保持一致
  • 直接使用SwiftUI的Font.custom创建字体,更贴合SwiftUI生态,无需依赖UIFont

修改后,用户选择字体时只会切换字体家族,字号将保留当前文本使用的大小,无需固定指定数值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:05:57