SwiftUI Dark Mode: The Complete Implementation Guide
Source: Dev.to
Detecting the Current Color Scheme
SwiftUI provides @Environment(\.colorScheme) to detect whether the app is in light or dark mode.
struct ContentView: View {
@Environment(\.colorScheme) var colorScheme
var body: some View {
Text("Hello")
.foregroundColor(colorScheme == .dark ? .white : .black)
}
}
Using Adaptive Colors
Instead of manually checking the color scheme, you can rely on SwiftUI’s built‑in adaptive colors.
Text("Adapts automatically")
.foregroundColor(.primary) // Black in light, white in dark
.background(Color(.systemBackground)) // White in light, black in dark
Key Semantic Colors
.primary/.secondary– text colors that adapt automatically.Color(.systemBackground)– main background color.Color(.secondarySystemBackground)– background for grouped content.
Creating a Custom Theme
For full control over colors, define a theme structure.
struct AppTheme {
let background: Color
let text: Color
let accent: Color
static let light = AppTheme(
background: .white,
text: .black,
accent: .blue
)
static let dark = AppTheme(
background: Color(.systemGray6),
text: .white,
accent: .cyan
)
}
Providing the Theme via Environment
Define an EnvironmentKey and extend EnvironmentValues to store the current theme.
struct ThemeKey: EnvironmentKey {
static let defaultValue = AppTheme.light
}
extension EnvironmentValues {
var theme: AppTheme {
get { self[ThemeKey.self] }
set { self[ThemeKey.self] = newValue }
}
}
Previewing Both Modes
Always test your UI in both light and dark appearances.
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
.preferredColorScheme(.light)
ContentView()
.preferredColorScheme(.dark)
}
}
}
Common Pitfalls
- Hard‑coding colors – Prefer semantic colors (
.primary,.secondary, system background colors) that adapt automatically. - Missing image assets – Provide dark‑mode variants or use SF Symbols, which adapt by default.
- Skipping previews – Always preview both light and dark schemes to catch visual issues early.