iOS SwiftUI应用中Swift Package Manager自定义字体配置失效问题及正确实现方案咨询
解决SPM自定义字体在SwiftUI中不生效的问题
我之前在SPM里配置自定义字体时也踩过几乎一模一样的坑,你的代码框架没问题,主要是两个关键环节没处理好——字体没有注册到系统和可能用错了字体的实际内部名称。下面是一步步的解决办法:
1. 先确认字体的正确内部名称(最容易踩的坑)
很多人会直接用字体文件名作为Font.custom()的参数,但字体的实际内部名称和文件名经常不一样(比如文件名是Gotham-Bold.otf,实际名称可能是Gotham Bold)。如果名称不匹配,系统找不到字体,就会 fallback 到一个默认的非SF字体,这就是你看到的异常现象。
怎么确认正确名称:
- 把你的
.otf字体拖进Mac的「字体册」 - 右键字体 → 「显示信息」
- 查看「全名」或者「PostScript名称」,这个才是你要在代码里用的字符串
2. 在SPM包中添加字体注册逻辑
SPM不会自动帮你把包内的字体注册到iOS系统中,必须手动写代码完成注册。在你的MyAwesomePackage里添加一个字体注册工具:
import UIKit public enum FontRegistrar { public static func registerCustomFonts() { // 替换成你从字体册里拿到的实际字体名称 let fontInfos = [ ("Gotham-Bold", "otf"), ("Gotham-Book", "otf"), ("Gotham-Medium", "otf") ] for (fontName, extensionType) in fontInfos { guard let fontURL = Bundle.module.url(forResource: fontName, withExtension: extensionType) else { print("❌ 找不到字体文件: \(fontName).\(extensionType)") continue } do { let fontData = try Data(contentsOf: fontURL) guard let dataProvider = CGDataProvider(data: fontData as CFData) else { print("❌ 无法创建字体数据提供者: \(fontName)") continue } guard let cgFont = CGFont(dataProvider) else { print("❌ 无法初始化CGFont: \(fontName)") continue } var registrationError: Unmanaged<CFError>? if !CTFontManagerRegisterGraphicsFont(cgFont, ®istrationError) { if let error = registrationError?.takeRetainedValue() { let errorDesc = CFErrorCopyDescription(error) print("❌ 注册字体失败 \(fontName): \(errorDesc ?? "未知错误" as CFString)") } } else { print("✅ 成功注册字体: \(fontName)") } } catch { print("❌ 加载字体数据失败 \(fontName): \(error.localizedDescription)") } } } }
这里用Bundle.module是SPM提供的专门用来访问包内资源的方式,能确保正确找到字体文件。
3. 在主应用启动时调用注册方法
打开你的主应用的App结构体,在初始化方法里调用注册逻辑,确保字体在应用启动时就被注册:
import MyAwesomePackage import SwiftUI @main struct YourAppName: App { init() { // 启动时注册SPM里的自定义字体 FontRegistrar.registerCustomFonts() } var body: some Scene { WindowGroup { ContentView() } } }
4. 修正CustomFontType中的字体名称
把CustomFontType里的customFont值替换成你从字体册里拿到的实际名称,比如如果实际名称是Gotham Bold,就改成:
var customFont: String { switch self { case .header: "Gotham Bold" // 替换成实际名称 case .body: "Gotham Book" case .link: "Gotham Medium" } }
最后验证
运行你的应用,现在自定义字体应该能正常显示了。如果还是有问题,可以看控制台的打印日志,排查是找不到字体文件还是注册失败,针对性解决。
内容的提问来源于stack exchange,提问作者Roland Lariotte
相关产品推荐
相关产品推荐

