Was ist Liquid Glass?
Mit iOS 26 hat Apple die wohl größte visuelle Überarbeitung seit iOS 7 eingeführt: Liquid Glass. Dieses neue dynamische Material kombiniert die optischen Eigenschaften von echtem Glas mit einem Gefühl von Flüssigkeit — und ehrlich gesagt, es verändert grundlegend, wie wir Oberflächen in unseren Apps gestalten.
Im Kern ist Liquid Glass ein transluzentes Material, das den darunter liegenden Inhalt in Echtzeit bricht und reflektiert. Anders als der klassische Blur-Effekt, den wir von .ultraThinMaterial kennen, nutzt Liquid Glass ein sogenanntes Lensing — es biegt und konzentriert Licht, anstatt es zu streuen. Dazu kommen spiegelnde Highlights, die auf Gerätebewegungen reagieren, adaptive Schatten und interaktive Verhaltensweisen bei Touch-Events. Klingt beeindruckend? Ist es auch.
Das Designsystem erstreckt sich plattformübergreifend über iOS 26, iPadOS 26, macOS Tahoe 26, watchOS 26, tvOS 26 und visionOS 26. Für uns SwiftUI-Entwickler heißt das: Ein einheitliches API-Set für alle Apple-Plattformen. Endlich.
Automatische Übernahme: Was sich von selbst ändert
Sobald du deine App mit Xcode 26 und dem iOS 26 SDK neu kompilierst, übernehmen viele System-Komponenten den Liquid-Glass-Look automatisch — ohne eine einzige Zeile Code zu ändern:
- NavigationBar, TabBar und Toolbar — erhalten transparente Glasoberflächen
- Sheets, Popovers, Menüs und Alerts — nutzen das neue Material
- Suchleisten und Control Center — passen sich an
- Toggles, Slider und Picker — zeigen während der Interaktion Glaseffekte
Das ist erst mal großartig — deine App sieht sofort moderner aus. Aber (und das ist ein wichtiges Aber) du solltest trotzdem prüfen, ob die automatischen Änderungen zu deinem bestehenden Design passen. Falls nicht, kannst du die Kompatibilitäts-Flag UIDesignRequiresCompatibility in deiner Info.plist auf YES setzen, um den alten Look beizubehalten.
Grundlagen: Der glassEffect-Modifier
Für eigene Views ist der .glassEffect()-Modifier dein Einstiegspunkt. So sieht die vollständige Signatur aus:
func glassEffect<S: Shape>(
_ glass: Glass = .regular,
in shape: S = DefaultGlassEffectShape,
isEnabled: Bool = true
) -> some View
Im einfachsten Fall reicht ein einziger Aufruf:
import SwiftUI
struct BasicGlassView: View {
var body: some View {
Text("Hallo, Liquid Glass!")
.padding()
.glassEffect()
}
}
Standardmäßig wird der Glaseffekt in einer Capsule-Form hinter deinem Inhalt gerendert. SwiftUI passt die Textfarbe automatisch an, damit sie auch vor farbigen Hintergründen gut lesbar bleibt. Ein nettes Detail, das dir einiges an Arbeit abnimmt.
Die drei Glass-Varianten
Die Glass-Struktur bietet drei statische Varianten, die du je nach Kontext einsetzen kannst:
.regular— Der Standard. Ein deutlich sichtbarer Glaseffekt mit moderater Transparenz. Ideal für Navigation und prominente UI-Elemente.clear— Subtiler und durchsichtiger. Gut für sekundäre Elemente oder Container, die weniger Aufmerksamkeit beanspruchen sollen.identity— Kein visueller Glaseffekt, aber das Layout bleibt erhalten. Perfekt für Barrierefreiheits-Fallbacks
// Regular — deutlich sichtbar
Text("Primär")
.padding()
.glassEffect(.regular)
// Clear — dezenter
Text("Sekundär")
.padding()
.glassEffect(.clear)
// Identity — kein visueller Effekt
Text("Fallback")
.padding()
.glassEffect(.identity)
Tinting: Glaseffekte einfärben
Mit der .tint()-Methode kannst du den Glaseffekt farblich anpassen. Das ist besonders praktisch, um visuelle Hierarchien zu schaffen oder dein Branding einzubinden:
// Blauer Tint
Text("Info")
.padding()
.glassEffect(.regular.tint(.blue))
// Dezenter lila Tint mit Transparenz
Text("Hinweis")
.padding()
.glassEffect(.regular.tint(.purple.opacity(0.6)))
// Branding-Farbe
Text("Marke")
.padding()
.glassEffect(.regular.tint(Color("BrandColor")))
Wichtig zu wissen: Der Tint beeinflusst nur den Glaseffekt selbst — er überschreibt nicht die Textfarbe. SwiftUI wählt weiterhin automatisch eine gut lesbare Vordergrundfarbe. Das musst du also nicht manuell regeln.
Formen anpassen
Die Form des Glaseffekts lässt sich über den zweiten Parameter steuern. SwiftUI bietet sowohl eingebaute als auch benutzerdefinierte Shapes:
// Capsule (Standard)
.glassEffect(.regular, in: .capsule)
// Kreis — ideal für runde Buttons
.glassEffect(.regular, in: .circle)
// Abgerundetes Rechteck mit eigenem Radius
.glassEffect(.regular, in: RoundedRectangle(cornerRadius: 16))
// Container-konzentrische Ecken
.glassEffect(.regular, in: .rect(cornerRadius: .containerConcentric))
Die Option .containerConcentric ist dabei besonders clever: Sie passt den Eckradius automatisch an den umgebenden Container an, sodass verschachtelte Glaselemente visuell harmonisch wirken. Das spart dir manuelle Berechnungen — was ich persönlich sehr schätze.
Eigene Shapes verwenden
Du kannst auch komplett eigene Shapes definieren und als Glasform nutzen:
struct AbgerundetesPolygon: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let breite = rect.width
let hoehe = rect.height
path.move(to: CGPoint(x: breite * 0.5, y: 0))
path.addLine(to: CGPoint(x: breite, y: hoehe * 0.35))
path.addLine(to: CGPoint(x: breite * 0.8, y: hoehe))
path.addLine(to: CGPoint(x: breite * 0.2, y: hoehe))
path.addLine(to: CGPoint(x: 0, y: hoehe * 0.35))
path.closeSubpath()
return path
}
}
// Verwendung
Image(systemName: "star.fill")
.font(.largeTitle)
.frame(width: 100, height: 100)
.glassEffect(.regular, in: AbgerundetesPolygon())
Interaktive Glaseffekte
Jetzt wird's richtig spannend. Für tappbare Elemente wie Buttons oder Controls bietet Liquid Glass interaktive Verhaltensweisen — Skalierung, Bounce und ein subtiles Schimmern bei Berührung. Aktiviert wird das mit .interactive():
struct InteraktiveGlasButtons: View {
var body: some View {
HStack(spacing: 20) {
Button(action: { /* Aktion */ }) {
Image(systemName: "heart.fill")
.font(.title2)
.frame(width: 56, height: 56)
}
.glassEffect(.regular.interactive(), in: .circle)
Button(action: { /* Aktion */ }) {
Label("Teilen", systemImage: "square.and.arrow.up")
.padding(.horizontal, 16)
.padding(.vertical, 10)
}
.glassEffect(.regular.interactive())
}
}
}
Die Regel ist simpel: Verwende .interactive() nur bei Elementen, die der Nutzer auch tatsächlich antippen kann. Dekorative Glasflächen sollten nicht interaktiv sein — das verwirrt sonst die Nutzererwartung.
Eingebaute Button-Styles
SwiftUI bringt außerdem zwei dedizierte Glass-Button-Styles mit:
// Transparenter Glass-Button — für sekundäre Aktionen
Button("Abbrechen") { }
.buttonStyle(.glass)
// Opaker, prominenter Glass-Button — für primäre Aktionen
Button("Speichern") { }
.buttonStyle(.glassProminent)
Gerade .glassProminent finde ich super für Call-to-Action-Buttons — er sticht hervor, ohne den typischen Liquid-Glass-Look zu verlieren.
GlassEffectContainer: Mehrere Glaselemente gruppieren
Wenn du mehrere Glaselemente nebeneinander platzierst, solltest du sie in einem GlassEffectContainer gruppieren. Und das ist nicht nur eine nette Empfehlung — es ist essenziell für die korrekte Darstellung.
Warum? Liquid Glass erzeugt seinen visuellen Effekt, indem es einen Bereich größer als das Element selbst samplet und verarbeitet. Das Problem dabei: Glas kann kein anderes Glas samplen. Ohne Container würden nebeneinanderliegende Glaselemente inkonsistente visuelle Artefakte erzeugen. Nicht schön.
struct GlassToolbar: View {
var body: some View {
GlassEffectContainer {
HStack(spacing: 16) {
Button(action: {}) {
Image(systemName: "house.fill")
.frame(width: 44, height: 44)
}
.glassEffect(.regular.interactive(), in: .circle)
Button(action: {}) {
Image(systemName: "magnifyingglass")
.frame(width: 44, height: 44)
}
.glassEffect(.regular.interactive(), in: .circle)
Button(action: {}) {
Image(systemName: "person.fill")
.frame(width: 44, height: 44)
}
.glassEffect(.regular.interactive(), in: .circle)
}
.padding()
}
}
}
Spacing und Morphing
Der GlassEffectContainer akzeptiert einen optionalen spacing-Parameter. Dieser Wert bestimmt den Morphing-Schwellenwert: Wie nah müssen zwei Glaselemente sein, damit sie visuell zu einer einzigen Form verschmelzen?
// Elemente verschmelzen bei weniger als 40pt Abstand
GlassEffectContainer(spacing: 40) {
HStack(spacing: 20) {
// Diese Elemente werden visuell verbunden
Text("A").padding().glassEffect()
Text("B").padding().glassEffect()
}
}
// Elemente bleiben getrennt
GlassEffectContainer(spacing: 8) {
HStack(spacing: 20) {
// Diese Elemente bleiben eigenständig
Text("A").padding().glassEffect()
Text("B").padding().glassEffect()
}
}
Spiel ruhig ein bisschen mit den Werten rum — der visuelle Unterschied ist überraschend groß.
Morphing-Animationen mit glassEffectID
Eine der beeindruckendsten Funktionen von Liquid Glass sind die fließenden Morphing-Übergänge zwischen Zuständen. Dafür nutzt du glassEffectID zusammen mit dem @Namespace-Property-Wrapper:
struct MorphingDemo: View {
@State private var istErweitert = false
@Namespace private var namespace
var body: some View {
GlassEffectContainer(spacing: 40) {
HStack(spacing: 40) {
Button(action: {}) {
Image(systemName: "pencil")
.frame(width: 60, height: 60)
}
.glassEffect(.regular.interactive(), in: .circle)
.glassEffectID("stift", in: namespace)
if istErweitert {
Button(action: {}) {
Image(systemName: "eraser.fill")
.frame(width: 60, height: 60)
}
.glassEffect(.regular.interactive(), in: .circle)
.glassEffectID("radierer", in: namespace)
Button(action: {}) {
Image(systemName: "paintbrush.fill")
.frame(width: 60, height: 60)
}
.glassEffect(.regular.interactive(), in: .circle)
.glassEffectID("pinsel", in: namespace)
}
}
}
Button(istErweitert ? "Zuklappen" : "Aufklappen") {
withAnimation(.spring(duration: 0.4)) {
istErweitert.toggle()
}
}
.buttonStyle(.glass)
.padding(.top, 20)
}
}
Durch die glassEffectID weiß SwiftUI, welche Glaselemente zusammengehören — und animiert Erscheinen, Verschwinden und Positionsänderungen als fließende Morphing-Übergänge. In der Praxis sieht das wirklich fantastisch aus, besonders bei Toolbar-Erweiterungen.
Praxisbeispiel: Floating Action Menu
So, jetzt bringen wir alles zusammen. Hier ist ein realistisches Beispiel — ein Floating Action Menu mit Liquid Glass:
struct FloatingActionMenu: View {
@State private var istOffen = false
@Namespace private var menuNamespace
var body: some View {
ZStack(alignment: .bottomTrailing) {
// Dein Hauptinhalt
ScrollView {
LazyVStack(spacing: 12) {
ForEach(0..<20, id: \.self) { index in
Text("Element \(index)")
.frame(maxWidth: .infinity)
.padding()
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 12))
}
}
.padding()
}
// Floating Action Menu
VStack(alignment: .trailing, spacing: 16) {
GlassEffectContainer(spacing: 30) {
VStack(alignment: .trailing, spacing: 12) {
if istOffen {
MenuButton(
icon: "camera.fill",
label: "Foto",
id: "foto",
namespace: menuNamespace
)
MenuButton(
icon: "doc.fill",
label: "Dokument",
id: "dokument",
namespace: menuNamespace
)
MenuButton(
icon: "link",
label: "Link",
id: "link",
namespace: menuNamespace
)
}
Button(action: {
withAnimation(.spring(duration: 0.35)) {
istOffen.toggle()
}
}) {
Image(systemName: istOffen ? "xmark" : "plus")
.font(.title2.bold())
.frame(width: 56, height: 56)
.contentTransition(.symbolEffect(.replace))
}
.glassEffect(
.regular.interactive().tint(.blue),
in: .circle
)
.glassEffectID("hauptbutton", in: menuNamespace)
}
}
}
.padding(24)
}
}
}
struct MenuButton: View {
let icon: String
let label: String
let id: String
let namespace: Namespace.ID
var body: some View {
Button(action: { /* Aktion */ }) {
Label(label, systemImage: icon)
.padding(.horizontal, 16)
.padding(.vertical, 10)
}
.glassEffect(.regular.interactive())
.glassEffectID(id, in: namespace)
.transition(.scale.combined(with: .opacity))
}
}
Dieses Beispiel zeigt schön, wie GlassEffectContainer, interaktive Glaseffekte und Morphing-IDs zusammenspielen. Das Ergebnis ist ein flüssiges, modernes UI-Erlebnis — und deine Nutzer werden den Unterschied merken.
Migration bestehender Apps
Du fragst dich jetzt vielleicht: Muss ich meine komplette App umbauen? Die kurze Antwort: Nein. Apple hat die Migration bewusst schrittweise gestaltet — und das ist auch gut so.
Schritt 1: Kompilieren und prüfen
Kompiliere deine App mit Xcode 26 und dem iOS 26 SDK. System-Komponenten übernehmen Liquid Glass automatisch. Dann einfach visuell durchgehen und schauen, ob alles passt.
Schritt 2: Kompatibilitätsmodus bei Bedarf
Falls die automatischen Änderungen problematisch sind, kannst du über die Info.plist den Kompatibilitätsmodus aktivieren:
<key>UIDesignRequiresCompatibility</key>
<true/>
Schritt 3: Schrittweise Übernahme
Ersetze nach und nach deine bisherigen Material-Effekte durch die neuen Glass-APIs:
// Vorher (iOS 15+)
Text("Alt")
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
// Nachher (iOS 26+)
Text("Neu")
.padding()
.glassEffect(.regular, in: RoundedRectangle(cornerRadius: 16))
Der Umstieg ist im Grunde unkompliziert — meistens reicht es, .background(.ultraThinMaterial, ...) durch .glassEffect() zu ersetzen.
Abwärtskompatibilität sicherstellen
Wenn deine App auch ältere iOS-Versionen unterstützen muss (was wahrscheinlich der Fall ist), nutze Verfügbarkeitsprüfungen:
if #available(iOS 26, *) {
Text("Modern")
.padding()
.glassEffect(.regular, in: .rect(cornerRadius: 16))
} else {
Text("Modern")
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
}
Apple hat angekündigt, dass die vollständige Umstellung auf Liquid Glass voraussichtlich bis iOS 27 erwartet wird — du hast also noch Zeit. Aber ich würde empfehlen, jetzt schon mit der schrittweisen Migration zu beginnen.
UIKit-Integration
Falls dein Projekt UIKit verwendet oder eine hybride Architektur hat, kannst du Liquid Glass auch dort einsetzen. Apple hat UIVisualEffectView für iOS 26 aktualisiert:
// UIKit: Liquid Glass für eine View
let glassView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial))
glassView.frame = CGRect(x: 0, y: 0, width: 200, height: 60)
view.addSubview(glassView)
In einer hybriden SwiftUI/UIKit-App solltest du darauf achten, dass die Designsprache in beiden Teilen konsistent bleibt. Mein Tipp: Migriere schrittweise einzelne Screens und wiederverwendbare Komponenten, statt alles auf einmal anzufassen. So bleibst du in der Kontrolle.
Performance und Best Practices
Liquid Glass nutzt Metal und optimierte Shader für GPU-beschleunigte Echtzeit-Effekte. Auf modernen iPhones läuft das flüssig mit 120 Hz. Trotzdem gibt es ein paar Punkte, die du beachten solltest.
Do's
- Wende
.glassEffect()als letzten Modifier an — nach allen anderen Appearance-Modifiern wie.padding(),.font()oder.foregroundStyle() - Nutze
GlassEffectContainerimmer dann, wenn mehrere Glaselemente zusammen dargestellt werden - Halte die Anzahl der Glaselemente pro View moderat — 5–10 Elemente sind in der Regel kein Problem
- Teste auf echten Geräten — der Simulator zeigt den Effekt, aber Performance-Messungen sind nur auf echter Hardware aussagekräftig
Don'ts
- Kein Liquid Glass auf weißen oder sehr hellen Hintergründen — der Effekt lebt von Kontrast mit dem darunter liegenden Inhalt
- Nicht in langen, scrollbaren Listen verwenden — jede Zelle mit Glass-Effekt belastet die GPU unnötig
- Keinen kleinen Text in Glasflächen — die Lesbarkeit leidet trotz automatischer Farbanpassung
- Kein Vollbild-Glass — Liquid Glass ist für die Navigationsebene gedacht, nicht für Hauptinhalte
Ein Fehler, den ich anfangs selbst gemacht habe: Glaseffekte überall einsetzen, weil sie so gut aussehen. Weniger ist hier definitiv mehr.
Barrierefreiheit
Apple hat von Anfang an Accessibility-Unterstützung in Liquid Glass integriert. Trotzdem solltest du ein paar Dinge aktiv berücksichtigen:
struct BarrierefreieGlassView: View {
@Environment(\.accessibilityReduceTransparency) var transparenzReduziert
var body: some View {
Text("Zugänglich")
.padding()
.glassEffect(transparenzReduziert ? .identity : .regular)
}
}
Wenn der Nutzer in den Systemeinstellungen „Transparenz reduzieren" aktiviert hat, wechselst du auf .identity — das behält das Layout bei, entfernt aber den visuellen Glaseffekt. In den meisten Fällen übernimmt das System diese Anpassung automatisch. Du musst nur eingreifen, wenn du benutzerdefinierte Glass-Elemente gebaut hast.
Achte außerdem auf ausreichenden Kontrast und teste unbedingt mit Dynamic Type in verschiedenen Größen. Glaselemente können bei größeren Schriftarten schnell überlaufen — das ist leicht zu übersehen.
Häufig gestellte Fragen
Muss ich meine App komplett umbauen, um Liquid Glass zu unterstützen?
Nein. Sobald du mit Xcode 26 kompilierst, übernehmen System-Komponenten wie NavigationBar, TabBar und Sheets den Liquid-Glass-Look automatisch. Für eigene Views kannst du schrittweise migrieren. Apple erzwingt die vollständige Übernahme voraussichtlich erst mit iOS 27.
Funktioniert Liquid Glass auch mit UIKit?
Ja. Apple hat UIVisualEffectView für iOS 26 aktualisiert, sodass auch UIKit-basierte Apps Liquid Glass nutzen können. System-Elemente übernehmen den Look automatisch. Für eigene Views brauchst du allerdings etwas mehr manuellen Aufwand als in SwiftUI.
Welche Geräte unterstützen Liquid Glass?
Liquid Glass läuft auf allen Geräten, die iOS 26 unterstützen. Die GPU-beschleunigten Effekte nutzen Metal und optimierte Shader, die auf modernen Apple-Silicon-Chips mit 120 Hz laufen. Auch ältere unterstützte Geräte zeigen den Effekt — nur gegebenenfalls mit reduzierten visuellen Details.
Was ist der Unterschied zwischen .regular, .clear und .identity?
.regular ist der Standard-Glaseffekt mit deutlicher Transparenz. .clear ist subtiler und weniger auffällig — ideal für sekundäre Elemente. .identity entfernt den visuellen Effekt komplett, behält aber das Layout bei — perfekt als Barrierefreiheits-Fallback oder für bedingte Darstellung.
Warum brauche ich einen GlassEffectContainer?
Liquid Glass erzeugt seinen Effekt, indem es einen größeren Bereich als das Element selbst samplet. Das Problem: Glas kann kein anderes Glas samplen. Ohne Container würden nebeneinanderliegende Glaselemente visuelle Artefakte zeigen. Der GlassEffectContainer ermöglicht es den Elementen, ihre Sampling-Region zu teilen, und kontrolliert zudem das Morphing-Verhalten bei Animationen.