← Files Build iOS AppsARCHIVED FILE
skills/swiftui-ui-patterns/references/theming.md
1.73 KB · Oct 2, 2026 · 00:37 UTC
# Theming and dynamic type
## Intent
Provide a clean, scalable theming approach that keeps view code semantic and consistent.
## Core patterns
- Use a single `Theme` object as the source of truth (colors, fonts, spacing).
- Inject theme at the app root and read it via `@Environment(Theme.self)` in views.
- Prefer semantic colors (`primaryBackground`, `secondaryBackground`, `label`, `tint`) instead of raw colors.
- Keep user-facing theme controls in a dedicated settings screen.
- Apply Dynamic Type scaling through custom fonts or `.font(.scaled...)`.
## Example: Theme object
```swift
@MainActor
@Observable
final class Theme {
var tintColor: Color = .blue
var primaryBackground: Color = .white
var secondaryBackground: Color = .gray.opacity(0.1)
var labelColor: Color = .primary
var fontSizeScale: Double = 1.0
}
```
## Example: inject at app root
```swift
@main
struct MyApp: App {
@State private var theme = Theme()
var body: some Scene {
WindowGroup {
AppView()
.environment(theme)
}
}
}
```
## Example: view usage
```swift
struct ProfileView: View {
@Environment(Theme.self) private var theme
var body: some View {
VStack {
Text("Profile")
.foregroundStyle(theme.labelColor)
}
.background(theme.primaryBackground)
}
}
```
## Design choices to keep
- Keep theme values semantic and minimal; avoid duplicating system colors.
- Store user-selected theme values in persistent storage if needed.
- Ensure contrast between text and backgrounds.
## Pitfalls
- Avoid sprinkling raw `Color` values in views; it breaks consistency.
- Do not tie theme to a single view’s local state.
- Avoid using `@Environment(\\.colorScheme)` as the only theme control; it should complement your theme.
SHA-256: cbf2bac6a2e115fe0d2ef55e943736e74d5652baef620ac10cd6cbc689e07981