SwiftUI自定义字体图标不显示但UIKit正常问题咨询
问题原因分析与解决方案
可能的核心原因
1. 字符串Unicode解析差异
如果SimplifiIcons中的图标字符串定义存在编码问题,会导致UIKit和SwiftUI场景下实际传递的字符不一致:
- 若
SimplifiIcons是Objective-C模块中通过宏定义的(如#define IC_SP_TIMER_ICON @"\ue001"),Swift导入后会自动完成Unicode转义,得到正确的图标字符; - 但如果是Swift中定义的字符串写法错误(比如写成
"\\uE001",即额外转义了反斜杠),直接在SwiftUI中访问时,实际传递的是"\uE001"文本字符串,而非对应的Unicode图标字符。
2. 自定义字体加载时机问题
UIKit环境下,字体可能在App启动后已提前加载完成;而直接在SwiftUI视图中渲染时,字体可能还未完成注册,导致系统找不到Font-Icon字体,无法渲染图标。
3. 字体名称匹配错误
Font.custom("Font-Icon", size: size)中的字体名称可能与实际字体文件的内部名称不匹配——字体文件名和其内部逻辑名称经常不一致(比如文件名是FontIcon.ttf,但内部名称是FontIcon-Regular),UIKit可能通过其他方式兼容了这个问题,但SwiftUI严格匹配名称导致失败。
具体排查与解决步骤
1. 验证字符串的实际Unicode值
在两种场景下打印字符串的Unicode标量,确认是否一致:
// UIKit传递前打印 print(Array(SimplifiIcons.ic_sp_timer_icon.unicodeScalars)) // SwiftUI视图中分别打印传参和直接访问的结果 struct PresetDetailsView: View { var iconName: String var body: some View { Text(iconName).font(.fontIcon(20)) .onAppear { print("传参的Unicode标量:\(Array(iconName.unicodeScalars))") print("直接访问的Unicode标量:\(Array(SimplifiIcons.ic_sp_timer_icon.unicodeScalars))") } } }
如果结果不同,修正SimplifiIcons的定义,确保是正确的Unicode字符:
enum SimplifiIcons { // 方式1:使用大括号包裹的Unicode标量写法 static let ic_sp_timer_icon = "\u{E001}" // 方式2:通过UnicodeScalar直接初始化(更稳妥) static let ic_sp_timer_icon = String(UnicodeScalar(0xE001)!) }
2. 提前加载自定义字体
在App启动阶段手动注册字体,确保SwiftUI渲染时字体已就绪:
func loadCustomIconFont() { guard let fontURL = Bundle.main.url(forResource: "Font-Icon", withExtension: "ttf"), let fontData = try? Data(contentsOf: fontURL), let provider = CGDataProvider(data: fontData as CFData), let cgFont = CGFont(provider) else { print("加载自定义字体失败") return } var error: Unmanaged<CFError>? CTFontManagerRegisterGraphicsFont(cgFont, &error) if let error = error?.takeRetainedValue() { print("字体注册错误:\(error.localizedDescription)") } }
在AppDelegate的didFinishLaunchingWithOptions或SwiftUI的App结构体中调用该方法:
@main struct YourApp: App { init() { loadCustomIconFont() } var body: some Scene { WindowGroup { ContentView() } } }
3. 确认字体的正确名称
打开Mac的「字体册」,导入你的Font-Icon字体,查看其全称(比如Font-Icon-Regular),然后修正Font扩展:
extension Font { static func fontIcon(_ size: CGFloat) -> Font { Font.custom("Font-Icon-Regular", size: size) // 使用字体册中显示的正确名称 } }
内容的提问来源于stack exchange,提问作者Sarath Kumar
相关产品推荐
相关产品推荐

