部分字体无法应用到SwiftUI特定视图的问题求助
SwiftUI中EnvironmentObject字体切换部分字体不生效问题
在SwiftUI项目中,基于EnvironmentObject实现了字体切换功能:设置菜单内的所有内置及第三方字体均可正常渲染,但在PostView等其他视图中,部分字体(如Trebuchet、Roboto等)无法生效。已确认EnvironmentObject已注入根视图,调试打印显示字体名称正确传递,但问题仍存在。
最小复现示例(仅使用内置字体)
@main struct FontExampleApp: App { @StateObject private var appearanceManager = AppearanceManager() var body: some Scene { WindowGroup { ContentView() .environmentObject(appearanceManager) } } } class AppearanceManager: ObservableObject { @Published var Font: String = "System" { didSet { saveFont() objectWillChange.send() print("Set font to \(Font)") print("Corresponding font name: \(fonts[Font])") } } public let fonts = ["System" : "system-default", // unrecognized name defaults to system font "Times New Roman" : "TimesNewRomanPSMT", "Trebuchet" : "TrebuchetMS" ] init() { loadFont() for family in UIFont.familyNames.sorted() { let names = UIFont.fontNames(forFamilyName: family) print("Family: \(family) Font names: \(names)") } } private let fontKey = "FontKey" private func saveFont() { UserDefaults.standard.set(Font, forKey: fontKey) } private func loadFont() { if let savedFont = UserDefaults.standard.value(forKey: fontKey) as? String { Font = savedFont } } } struct ContentView: View { var body: some View { VStack { PostView() Spacer() FontSelectionView() } .padding() } } struct PostView: View { @EnvironmentObject var appearanceManager: AppearanceManager var body: some View { ScrollView { VStack(alignment: .leading, spacing: 16) { Text("Hello World") // below only works for certain fonts .font(.custom(appearanceManager.Font, size: 30, relativeTo: .title)) } .padding() } } } struct FontSelectionView: View { @EnvironmentObject var appearanceManager: AppearanceManager var body: some View { Section(header: Text("Fonts")) { VStack(alignment: .leading) { ForEach(appearanceManager.fonts.keys.sorted(), id: \.self) { fontName in FontButton(name: fontName) } .padding(.vertical, 5) } } } } struct FontButton: View { @EnvironmentObject var appearanceManager: AppearanceManager let name: String var isSelected: Bool { appearanceManager.Font == name } var body: some View { HStack { Text(name) .font(.custom(appearanceManager.fonts[name] ?? "", size: 17, relativeTo: .body)) Spacer() Circle() .frame(width: 20, height: 20) .foregroundColor(isSelected ? .secondary : .clear) .overlay( Circle() .stroke(Color.primary, lineWidth: 2) ) } .foregroundColor(.secondary) .onTapGesture { withAnimation { appearanceManager.Font = name } } } }
该示例中Times New Roman可正常生效,但Trebuchet无法应用到PostView的文本上。
调试打印信息
添加第三方字体后,设置菜单内所有字体均可正常显示,但PostView等视图仍存在部分字体无法生效的问题,调试打印显示字体名称已正确传递:
// 初始化时打印的字体信息 ... Family: Times New Roman Font names: ["TimesNewRomanPSMT", "TimesNewRomanPS-ItalicMT", "TimesNewRomanPS-BoldMT", "TimesNewRomanPS-BoldItalicMT"] Family: Trebuchet MS Font names: ["TrebuchetMS", "TrebuchetMS-Italic", "TrebuchetMS-Bold", "Trebuchet-BoldItalic"] Family: Ubuntu Mono Font names: ["UbuntuMono-Regular"] ... // 切换字体时的打印 Set font to Trebuchet Corresponding font name: Optional("TrebuchetMS") // 未在设置菜单外生效 Set font to JetBrains Mono Corresponding font name: Optional("JetBrainsMono-Regular") // 正常生效 Set font to Roboto Corresponding font name: Optional("RobotoMono-Regular") // 未在设置菜单外生效
内容的提问来源于stack exchange,提问作者John Harrington
相关产品推荐
相关产品推荐

