SwiftUI Dark Mode implementieren – Der komplette Guide
SwiftUI Dark Mode richtig umsetzen mit Systemfarben, Asset-Katalogen, @Environment und manuellem Toggle. Inklusive typischer Fehler und Best Practices.

Warum Dark Mode in jeder App Standard sein sollte
Der Dark Mode ist kein Trend mehr, sondern eine Erwartung. Seit iOS 13 können Nutzer systemweit zwischen Light und Dark Mode wechseln. Die Mehrheit der Smartphone-Nutzer hat den Dark Mode zumindest zeitweise aktiv. Apps die ihn nicht unterstützen, fallen sofort negativ auf.
Die Vorteile im Überblick:
- Weniger Augenbelastung bei schlechten Lichtverhältnissen
- Spürbar weniger Akkuverbrauch auf OLED-Displays
- Bessere Lesbarkeit für Nutzer mit Lichtempfindlichkeit
- Modernes Erscheinungsbild, das professioneller wirkt
Wie SwiftUI den Dark Mode handhabt
SwiftUI unterstützt den Dark Mode von Haus aus, solange du die richtigen Farben verwendest. Das System erkennt automatisch ob Light oder Dark Mode aktiv ist und passt Farben entsprechend an.
| Farbtyp | Light Mode | Dark Mode | Automatisch? |
|---|---|---|---|
Color.primary |
Schwarz | Weiß | Ja |
Color.secondary |
Grau | Hellgrau | Ja |
Color(.systemBackground) |
Weiß | Schwarz | Ja |
Hardcoded Color.white |
Weiß | Weiß | Nein |
| Asset-Katalog Farben | Frei wählbar | Frei wählbar | Ja |
Kernregel: Verwende niemals hardcoded Farben wie Color.white oder Color.black für Hintergründe und Text. Nutze stattdessen semantische Farben.
Schritt 1: Systemfarben verwenden
Die einfachste Methode. SwiftUI passt alles automatisch an:
VStack {
Text("Überschrift")
.foregroundStyle(.primary)
Text("Beschreibung")
.foregroundStyle(.secondary)
}
.background(Color(.systemBackground))
.primary, .secondary und die UIColor-Systemfarben wechseln automatisch zwischen Light und Dark Mode.
Schritt 2: Eigene Farben im Asset-Katalog
Für Markenfarben die in beiden Modi funktionieren sollen:
- Öffne
Assets.xcassetsin Xcode - Klicke + → Color Set
- Im Attribut-Inspektor: Appearances → Any, Dark
- Setze für jeden Modus die passende Farbe
In SwiftUI dann:
Text("Markenfarbe")
.foregroundStyle(Color("brandPrimary"))
Tipp: Erstelle ein Farb-Set für jede semantische Rolle, nicht für jede Farbe:
| Color Set Name | Verwendung |
|---|---|
brandPrimary |
Hauptfarbe (Buttons, Links) |
brandBackground |
Seitenhintergrund |
cardBackground |
Karten, Panels |
textPrimary |
Haupttext |
textSecondary |
Nebentext, Hints |
divider |
Trennlinien |
Schritt 3: Preview in beiden Modi
Die einfachste Methode:
#Preview {
ContentView()
.preferredColorScheme(.dark)
}
Für beide Modi gleichzeitig:
#Preview("Light") {
ContentView()
.preferredColorScheme(.light)
}
#Preview("Dark") {
ContentView()
.preferredColorScheme(.dark)
}
Im Simulator: Einstellungen → Entwickler → Dunkle Darstellung umschalten. Oder schneller: Xcode → Debug → Simulate Appearance → Dark.
Schritt 4: Manueller Dark Mode Toggle in der App
Manche Apps bieten einen eigenen Dark/Light/System-Schalter. So implementierst du das:
enum AppTheme: String, CaseIterable {
case system, light, dark
var colorScheme: ColorScheme? {
switch self {
case .system: nil
case .light: .light
case .dark: .dark
}
}
}
@main
struct MyApp: App {
@AppStorage("appTheme") private var appTheme: AppTheme = .system
var body: some Scene {
WindowGroup {
ContentView()
.preferredColorScheme(appTheme.colorScheme)
}
}
}
Seit Swift 5.9 kannst du if/switch als Expression verwenden, das return ist nicht mehr nötig.
Der Toggle in den Einstellungen:
struct SettingsView: View {
@AppStorage("appTheme") private var appTheme: AppTheme = .system
var body: some View {
Picker("Erscheinungsbild", selection: $appTheme) {
Text("System").tag(AppTheme.system)
Text("Hell").tag(AppTheme.light)
Text("Dunkel").tag(AppTheme.dark)
}
.pickerStyle(.segmented)
}
}
@AppStorage speichert die Auswahl automatisch in UserDefaults. Sie bleibt auch nach einem App-Neustart erhalten.
Wichtig: Wenn einzelne Views einen schwarzen Hintergrund erzwingen (z. B. ein Splash Screen), nutze .environment(\.colorScheme, .dark) statt .preferredColorScheme(.dark). Der Unterschied: preferredColorScheme wirkt auf das gesamte Fenster und kann vom App-Root überschrieben werden. .environment(\.colorScheme, ...) wirkt nur lokal auf die View und ihre Kinder.
Schritt 5: Aktuellen Modus abfragen
Mit @Environment kannst du in jeder View den aktiven Modus abfragen:
struct AdaptiveView: View {
@Environment(\.colorScheme) private var colorScheme
var body: some View {
Image(colorScheme == .dark ? "logo-light" : "logo-dark")
}
}
Nützlich für Bilder oder Grafiken die nicht über Asset-Kataloge adaptiert werden können.
Häufige Fehler
| Fehler | Problem | Lösung |
|---|---|---|
Color.white als Hintergrund |
Bleibt weiß im Dark Mode, blendet | Color(.systemBackground) verwenden |
Color.black für Text |
Unsichtbar im Dark Mode | .foregroundStyle(.primary) verwenden |
.foregroundColor() verwenden |
Deprecated seit iOS 17 | .foregroundStyle() verwenden |
.cornerRadius() verwenden |
Deprecated | .clipShape(.rect(cornerRadius: 12)) |
| Schatten mit fester Farbe | Sieht im Dark Mode falsch aus | shadow(color: .primary.opacity(0.1)) |
| Bilder ohne Dark-Variante | Logo auf dunklem Hintergrund unsichtbar | Asset-Katalog mit Any/Dark Variante |
#ffffff in HTML-WebViews |
WebView ignoriert Dark Mode | CSS prefers-color-scheme Media Query |
Fazit
SwiftUI macht Dark Mode Support einfach, vorausgesetzt du verwendest semantische Farben statt hardcoded Werte. Die drei wichtigsten Regeln:
- Systemfarben nutzen (
.primary,.secondary,Color(.systemBackground)) - Eigene Farben über Asset-Kataloge mit Light/Dark Varianten definieren
- Nie
Color.whiteoderColor.blackfür Hintergründe oder Text verwenden
Damit sieht deine App in beiden Modi professionell aus, und deine Nutzer können frei wählen.
Dieser Artikel wurde zuletzt am 5. April 2026 aktualisiert. Getestet mit Xcode 26 / iOS 26 / Swift 6.