主题化与动态字体
意图
提供清晰、可扩展的主题化方案,使视图代码保持语义化和一致性。
核心模式
- 使用单个
Theme对象作为唯一事实来源(颜色、字体、间距)。 - 在应用根节点注入主题,并在视图中通过
@Environment(Theme.self)读取。 - 优先使用语义化颜色(
primaryBackground、secondaryBackground、label、tint),而不是原始颜色。 - 将面向用户的主题控件放在专用的设置界面中。
- 通过自定义字体或
.font(.scaled...)应用动态字体缩放。
示例:Theme 对象
@MainActor@ObservablefinalclassTheme{vartintColor:Color=.bluevarprimaryBackground:Color=.whitevarsecondaryBackground:Color=.gray.opacity(0.1)varlabelColor:Color=.primaryvarfontSizeScale:Double=1.0}示例:在应用根节点注入
@mainstructMyApp:App{@Stateprivatevartheme=Theme()varbody:someScene{WindowGroup{AppView().environment(theme)}}}示例:视图中的使用
structProfileView:View{@Environment(Theme.self)privatevarthemevarbody:someView{VStack{Text("Profile").foregroundStyle(theme.labelColor)}.background(theme.primaryBackground)}}应保留的设计选择
- 保持主题值语义化且精简;避免重复系统颜色。
- 如有需要,将用户选择的主题值存储在持久化存储中。
- 确保文本与背景之间具有足够的对比度。
常见陷阱
- 避免在视图中散落原始
Color值;这会破坏一致性。 - 不要将主题绑定到单个视图的局部状态。
- 避免将
@Environment(\\.colorScheme)作为唯一的主题控制手段;它应作为主题的补充。