Liquid Glass in SwiftUI: Drei Muster aus dem Release von Return auf iOS 26
Apples Liquid Glass ist eine einzeilige SwiftUI-API: .glassEffect().1 Return, mein Meditations-Timer, nutzt es neunmal über iOS, macOS und tvOS hinweg.2 Eine dieser Verwendungen wendet den Modifier auf eine eigene Shape an, die die Timer-Ziffern selbst in Liquid Glass verwandelt, Glyphe für Glyphe.

Die interessante Frage ist, was passiert, wenn Sie über den Einzeiler hinausgehen. Apples Human Interface Guidelines legen eine strenge Schichtungsregel fest: Liquid Glass gehört in die funktionale Schicht (Bedienelemente, Navigation, transiente UI) und niemals in die Inhalts-Schicht.3 Die meisten der neun Verwendungen in Return sind musterhafte Anwendungen der funktionalen Schicht: Picker, Schaltflächen, Steuerleisten, Badges für den pausierten Zustand. Die interessanten Verwendungen sind jene drei, die die Regeln biegen, ohne sie zu brechen.
Dieser Essay führt durch drei Muster, die ich ausgeliefert habe, die Regeln, die sie respektieren, die Fallstricke, die mich erwischt haben, und die API-Oberfläche, die ich bewusst nicht verwendet habe.
Apples Human Interface Guidelines definieren Liquid Glass über drei Material-Varianten. Die reguläre Variante passt ihr Erscheinungsbild an das an, was unter ihr liegt (linkes Beispiel, dunkel; rechtes Beispiel, hell); die klare Variante lässt die darunterliegenden Details mit deutlich weniger Filterung durchscheinen:3



Referenzbilder von Apples Materials-HIG-Seite.3 Beide Varianten sind das, was .glassEffect() in SwiftUI erzeugt; die Wahl zwischen ihnen ist ein einzelnes Argument am Modifier.
TL;DR
- iOS 26 liefert Liquid Glass als
.glassEffect(_:in:)aus. Die Standardvariante ist.regularund die Standardform istCapsule.1 - Return nutzt drei Muster, die über den Einzeiler hinausgehen: Glas auf einer eigenen
Shape(Timer-Text via Core-Text-Glyphenpfade), das Spiegel-Muster (Reflexion darunter durch eine gespiegelte und maskierte Kopie) sowie HUD-Overlays in der funktionalen Schicht. - Apples HIG-Regel: Liquid Glass für die funktionale Schicht, Standard-Materialien für die Inhalts-Schicht.3
- Ich habe
GlassEffectContainerbewusst nicht verwendet. Die Morphing-API hat in Return keinen Anwendungsfall (kein Glaselement animiert sich in ein anderes hinein), und ich habe den Unterschied in der Rendering-Performance nicht gemessen; dies ist ein ungemessener Kompromiss, keine Empfehlung.1 - Fallstricke: Glas auf flachem Hintergrund wirkt flach; jitterfreies Ziffern-Rendering benötigt Zellen mit fester Breite; das
HStackvon tvOS ignoriert den Environment-Wert der Layout-Richtung; reduzierte Bewegung muss bei der Morph-Animation respektiert werden.
Für verwandte Apple-UI-Muster lesen Sie den Deep Dive zum SwiftUI Layout-Protokoll, das SF-Pro-Typografie-System und das Vokabular der Symbol Effects.
Die einzeilige API und die Schichtungsregel
Apple liefert Liquid Glass mit einer kleinen Oberfläche aus, eingeführt als wichtiger Design-Pfeiler auf der WWDC 2025:113
Text("Hello, World!")
.font(.title)
.padding()
.glassEffect() // default: .regular variant, Capsule shape
Text("Hello, World!")
.glassEffect(in: .rect(cornerRadius: 16)) // custom shape
Text("Hello, World!")
.glassEffect(.regular.tint(.orange).interactive()) // tint + touch reactivity
Drei Stellschrauben: Variante (.regular oder .clear), Form (jede beliebige Shape) und eine GlassEffectStyle-Kette (Tönung, interaktiv). Das ist die gesamte API für eine einzelne View. Mehr-View-Rendering wird von einem separaten GlassEffectContainer übernommen, auf den ich noch komme.
Die HIG ist strenger als die API. Apples Human Interface Guidelines definieren zwei Schichten in jeder Oberfläche ab iOS 26:3
- Die Inhalts-Schicht: das Dokument, die Liste, das Foto oder die Medien, die eine Person konsumiert. Verwenden Sie hier Standard-Materialien (die bestehenden
.regularMaterial,.thinMaterialusw.). - Die funktionale Schicht: Bedienelemente, Navigation, Tab-Bars, Seitenleisten, transiente Overlays. Verwenden Sie hier Liquid Glass.
Apples konkrete Anweisung: „Don’t use Liquid Glass in the content layer. Liquid Glass works best when it provides a clear distinction between interactive elements and content, and including it in the content layer can result in unnecessary complexity and a confusing visual hierarchy.”3
Die Regel klingt einschränkend, bis Sie sie auf eine reale App abbilden. Return ist ein Meditations-Timer. Seine Inhalts-Schicht sind die Atem-Bildwelten und das geloopte Video, das hinter allem läuft. Seine funktionale Schicht sind der Dauer-Picker, der Start/Pause/Stop-Schaltflächen-Stack, die sekundäre Reihe der Einstellungs-Schaltflächen und (auf tvOS) das Badge für den pausierten Zustand. Acht der neun Glas-Verwendungen in Return sind musterhafte Anwendungen der funktionalen Schicht: drei Varianten des Dauer-Pickers für die Code-Pfade von iOS und macOS, der Start/Pause-Umschalter, die Stop-Schaltfläche, die Reihe der Einstellungs-Schaltflächen, der tvOS-Indikator für den pausierten Zustand und ein weiteres transientes Bedien-Overlay.4
Die neunte ist der bewusste Grenzfall (Liquid Glass auf den Timer-Ziffern selbst), den der nächste Abschnitt durchgeht.
Muster 1: Glas auf einer eigenen Shape
Die Timer-Ziffern in Return sind kein Text, der über einen Glashintergrund gezeichnet wird. Das Glas ist der Text. .glassEffect(.clear, in:) akzeptiert jede beliebige Shape,9 und eine Shape ist ein Protokoll, das einen Path erzeugt.10 Der Trick ist also: den Timer-String mit Core Text in einen Pfad aus Glyphen umwandeln,11 dann diesen Pfad-als-Shape an .glassEffect übergeben.56
import SwiftUI
@preconcurrency import CoreText
struct GlassTextShape: Shape {
let text: String
let font: CTFont
func path(in rect: CGRect) -> Path {
guard !text.isEmpty else { return Path() }
let combinedPath = CGMutablePath()
let attrString = NSAttributedString(string: text, attributes: [.font: font])
let line = CTLineCreateWithAttributedString(attrString)
guard let runs = CTLineGetGlyphRuns(line) as? [CTRun], !runs.isEmpty else {
return Path()
}
for run in runs {
let glyphCount = CTRunGetGlyphCount(run)
guard glyphCount > 0 else { continue }
var glyphs = [CGGlyph](repeating: 0, count: glyphCount)
var positions = [CGPoint](repeating: .zero, count: glyphCount)
let range = CFRange(location: 0, length: glyphCount)
CTRunGetGlyphs(run, range, &glyphs)
CTRunGetPositions(run, range, &positions)
for i in 0..<glyphCount {
guard let glyphPath = CTFontCreatePathForGlyph(font, glyphs[i], nil) else { continue }
let transform = CGAffineTransform(translationX: positions[i].x, y: positions[i].y)
combinedPath.addPath(glyphPath, transform: transform)
}
}
// Core Text y-axis is flipped vs SwiftUI; flip then re-bound and center.
var swiftPath = Path(combinedPath).applying(CGAffineTransform(scaleX: 1, y: -1))
let flippedBounds = swiftPath.boundingRect
let offsetX = rect.midX - flippedBounds.midX
let offsetY = rect.midY - flippedBounds.midY
return swiftPath.applying(CGAffineTransform(translationX: offsetX, y: offsetY))
}
}
Echter Produktionscode aus Return/Return/GlassTextShape.swift.5 Die Funktion path(in:) nutzt Core Text, um den String zu setzen, läuft jeden CTRun durch, extrahiert den CGPath jeder Glyphe und vereint sie zu einem einzigen CGMutablePath. Die beiden nicht offensichtlichen Schritte kommen nach der Vereinigung: Das Koordinatensystem von Core Text platziert den Ursprung unten links, während der Path von SwiftUI ihn oben links setzt, sodass der Pfad via CGAffineTransform(scaleX: 1, y: -1) gespiegelt werden muss. Danach hat der boundingRect des gespiegelten Pfads negative y-Werte, sodass eine Translation ihn erneut innerhalb des Rechtecks zentriert, das SwiftUI der Shape übergibt. Lassen Sie eine der beiden Transformationen weg, und die Glyphen werden kopfüber oder außerhalb des Bildschirms gerendert.
Die Anwendung ist dann eine einzige Zeile:
Rectangle()
.fill(.clear)
.glassEffect(.clear, in: textShape)
.frame(width: cellWidth, height: cellHeight)
Das klare Rectangle ist ein Platzhalter als Trefferziel; die eigentliche Darstellung ist die Form, die textShape erzeugt. Mit einer Glyphenpfad-Form füllt das Liquid-Glass-Material nur die Glyphen-Umrisse. Das Ergebnis: Jede Ziffer des Timers ist eine eigene Liquid-Glass-Form, die alles bricht, was als Animation dahinter läuft.6
Die HIG-Nuance. Apples erklärte Regel lautet Liquid Glass für die funktionale Schicht, Standard-Materialien für die Inhalts-Schicht, mit einer ausdrücklichen Ausnahme: transiente interaktive Bedienelemente in der Inhalts-Schicht (Slider, Toggles) dürfen Liquid Glass annehmen, wenn sie aktiviert werden.3 Die Timer-Ziffern in Return sind eine Zustandsanzeige, kein Bedienelement: Sie aktualisieren sich einmal pro Sekunde aus Timer.publish(every: 1, ...) und haben keine Tipp-Geste (die Start/Pause-Schaltfläche darunter schaltet den Zustand um). Liquid Glass auf sie zu legen ist also ein bewusster Grenzfall, der dem „transienten interaktiven Bedienelement” der Absicht nach näher steht als der buchstäblichen Interaktivität, da die Ziffern der visuelle Fixpunkt sind, den Nutzer die gesamte Sitzung über betrachten. Ich biege die Regel, ich breche sie nicht. Wer die HIG streng liest, könnte argumentieren, dies solle Standard-Material sein; ich argumentiere, dass der Timer eine Bedienoberfläche für verstrichene Zeit ist, aus derselben Familie wie ein Fortschrittsindikator. Apples Dokumentation entscheidet diesen Fall nicht direkt.
Warum eine eigene Shape statt Text + Hintergrund. Text, der über einen Glashintergrund gerendert wird, wirkt wie Text auf Glas. Text, der als Glas selbst gerendert wird, wirkt wie eine andere visuelle Kategorie. Der Nutzer nimmt die Ziffern als funktionalen Vordergrund wahr, konkret als ein transientes Element, das existiert, um hindurchgeschaut zu werden, nicht angeschaut.
Muster 2: Das Spiegel-Muster
Return zeigt eine Reflexion des Timers darunter, die ausblendet. Echter Produktionscode:6

VStack(spacing: 0) {
GlassTimerText(text: displayTime, fontSize: fontSize)
.accessibilityLabel("Time remaining: \(accessibleDescription)")
if showReflection {
GlassTimerText(text: displayTime, fontSize: fontSize)
.scaleEffect(x: 1, y: -1)
.mask(
LinearGradient(
stops: [
.init(color: .white.opacity(0.2), location: 0),
.init(color: .clear, location: 0.6)
],
startPoint: .top,
endPoint: .bottom
)
)
.offset(y: -8)
.accessibilityHidden(true)
}
}
Drei Transformationen setzen den Spiegel zusammen, alle Standard-SwiftUI-Primitive:14
scaleEffect(x: 1, y: -1)dreht die zweite Kopie kopfüber..mask(LinearGradient(...))blendet die Reflexion von 20 % Deckkraft oben bis zu vollständiger Transparenz bei 60 % nach unten aus..offset(y: -8)zieht die Reflexion 8 Punkte nach oben, sodass sie an das Original anstößt, statt eine sichtbare Naht zu lassen.
Der Modifier .accessibilityHidden(true) auf der Reflexion ist tragend. VoiceOver sollte die gespiegelte Zeit nicht zweimal ansagen; das accessibilityLabel und accessibilityAddTraits(.updatesFrequently) des Originals sind bereits an die Haupt-Instanz von GlassTimerText oben angehängt, und die Reflexion ist rein dekorativ.
Warum das gerade mit Liquid Glass funktioniert. Die Reflexion erbt das Glasmaterial von GlassTimerText. Jeder Hintergrund, auf dem das Original sitzt (ein Atem-Kreis-Verlauf, ein Video, eine getönte Szene), bricht durch beide Kopien. Der Spiegel benötigt keinen glasspezifischen Code; das Glasmaterial übernimmt die Brechung kostenlos. Der gesamte Effekt sind drei Modifier und ein Verlauf.
Die Barrierefreiheits-Kosten. Nutzer mit reduzierter Bewegung sehen den Spiegel weiterhin, aber die Animation des Glasmaterials zwischen Zeit-Aktualisierungen wird andernorts via @Environment(\.accessibilityReduceMotion) unterdrückt.7 Die Reflexion selbst ist statisch; nur das Morphing zwischen Ziffern-Übergängen animiert.
Muster 3: Glas-HUD-Overlays für transiente Bedienelemente
Die übrigen acht Glas-Verwendungen in Return sind musterhafte Anwendungen der funktionalen Schicht.4 Jede folgt demselben Muster:

durationPicker
.frame(height: 50)
.frame(maxWidth: 320)
.glassEffect()
.padding(.horizontal, 20)
.transition(.opacity.combined(with: .scale(scale: 0.95)))
Das .transition(.opacity.combined(with: .scale(scale: 0.95))) ist der tragende Teil. Liquid Glass auf transienten Bedienelementen fühlt sich nur dann richtig an, wenn die Bedienelemente transitieren. Ein statisches Glas-HUD, das dauerhaft auf dem Bildschirm sitzt, wirkt wie Chrom. Ein Glas-HUD, das beim Tippen ein- und beim Wegschauen wieder ausblendet und skaliert, wirkt wie eine momentane Bedienoberfläche.
Apples Dokumentation zu glassEffect weist implizit darauf hin: Der Modifier „captures the content to send to the container to render” und „react[s] to touch and pointer interactions in real time.”1 Die Animations-Hooks sind nicht in der API, aber die Rendering-Pipeline geht davon aus, dass sich Glaselemente bewegen. Statischen Glaselementen entgeht diese Affordanz.
Return nutzt das Muster für den Dauer-Picker (gleitet beim Tippen nach oben), die Start/Pause-Umschalt-Schaltfläche (immer sichtbar, skaliert aber beim Drücken), die Stop-Schaltfläche (nur mitten in der Sitzung sichtbar), die Reihe der Einstellungs-Schaltflächen (eine horizontale Steuerleiste unter dem Dauer-Picker) und das tvOS-Badge für den pausierten Zustand (nur sichtbar, wenn eine Sitzung auf dem Apple TV pausiert ist). Alle fünf Kontexte respektieren die Regel der funktionalen Schicht aus der HIG.3

Referenz aus Apples HIG: Liquid-Glass-Overlays in tvOS sitzen über der Medien-Schicht und lassen sie durchscheinen.3 Die tvOS-Implementierung von Return folgt demselben Modell: Bedienelemente schweben über dem geloopten Feuer-/Wald-/Wasser-Hintergrund.
Eine Toolbar-Anmerkung aus den Labs. Ein WWDC-2026-SwiftUI-Group-Lab-Panel hat geschärft, wie sich das in Toolbars auswirkt. Nicht-Glas-Inhalt in eine Toolbar zu setzen — im Beispiel ein Profilfoto — verlangt sharedBackgroundVisibility(.hidden), damit das Element seinen geteilten Glashintergrund ablegt und das Foto direkt zeigt.15 Das Panel markierte eine Verfeinerung: Eine neuere API entfernt nur den Inhalts-Rand einer Toolbar-Schaltfläche, während zuvor das Ausblenden des Hintergrunds der einzige Hebel war und sowohl den Hintergrund als auch den Rand gemeinsam entfernte. Für Toolbar-Schaltflächen selbst lenkte das Panel hin zum prominenten Schaltflächenstil (glassProminent) und buttonBorderShape, statt direkt nach .glassEffect auf einer Schaltfläche zu greifen. Die zugrunde liegende HIG-Position ist dieselbe Schichtungsregel, um die sich dieser Beitrag dreht: Liquid Glass gehört ins Chrom, nicht in den Inhaltsbereich, denn eine Glasoberfläche, unter der nichts scrollt, hat nichts zu brechen.153
Die Frage nach dem GlassEffectContainer
Apple empfiehlt GlassEffectContainer, sobald eine App .glassEffect() auf mehreren Views nutzt, aus zwei Gründen: bessere Rendering-Performance (Glaseffekte werden gebündelt) und die Fähigkeit, Formen während Übergängen ineinander zu morphen.1
Ich habe ihn nicht verwendet. Die Begründung ist anwendungsspezifisch, keine Widerlegung von Apples Leitlinie. Return hat neun Glas-Views, von denen keine ineinander morphen muss.46 Der Dauer-Picker animiert sich nie in die Start-Schaltfläche hinein. Der Timer-Text animiert sich nie in die Reihe der Einstellungs-Schaltflächen. Jedes Glaselement ist eigenständig. Die Morphing-API hätte keinen Anwendungsfall, auf den sie reagieren könnte, und die Abstandsregeln des Containers würden Layouts einschränken, die heute keine Koordination benötigen.
Das Rendering-Performance-Argument kann ich ohne Messung nicht vollständig widerlegen. Apples Dokumentation warnt, dass „zu viele” Glaseffekte außerhalb eines Containers die Performance verschlechtern können.1 Die neun Views von Return teilen sich nie gleichzeitig den Bildschirm (der Dauer-Picker erscheint nur im Menü-Zustand, die Stop-Schaltfläche nur, wenn mitten in der Sitzung pausiert wurde). Bei einem beliebigen Frame zähle ich drei oder vier sichtbare Glaselemente, was auf jedem von mir getesteten Gerät über iOS, iPadOS, macOS, watchOS und tvOS hinweg flüssig war, aber ich habe keine Instruments-Aufzeichnung durchgeführt, die Container-umschlossen gegen modifier-only vergleicht. Daher die ehrliche Einordnung: Return verzichtet auf GlassEffectContainer auf Basis einer beobachtet guten Benutzererfahrung, nicht einer gemessenen Performance-Gleichwertigkeit.
Die Regel, die ich daraus gezogen habe: GlassEffectContainer ist für Apps, in denen mehrere Glaselemente gleichzeitig sichtbar sind und animieren. Apples Beispiel ist das Rendern eines Symbol-Sets mit glassEffectUnion(id:namespace:): vier Wettersymbole, die fließend als eine Einheit verschmelzen und sich teilen.1 Das ist ein musterhafter Anwendungsfall. Sollte eine künftige Return-Funktion verlangen, dass Glaselemente morphen oder sich die Abstandsregeln eines Containers teilen, ist der Container dann das richtige Werkzeug zum Hinzufügen. Für die heutige App bin ich auf den Fall noch nicht gestoßen.
Die Fallstricke, die mich erwischt haben
Drei echte Bugs aus der Produktion:
Jitter bei Glas-Ziffern. SF Pro Rounded hat bei proportionalem Rendering Ziffern variabler Breite. Während der Timer herunterzählte, änderte sich die Länge des angezeigten Strings, und das umgebende HStack floss jede Sekunde neu um, was den gesamten Timer ruckeln ließ. Die Lösung: Zellen mit fester Breite für jedes Zeichen. Jede Ziffer erhält eine cellWidth von fontSize * 0.6, jeder Doppelpunkt erhält fontSize * 0.3, und das HStack wird zu einem stabilen Raster.6
HStack(spacing: 0) {
ForEach(Array(text.enumerated()), id: \.offset) { _, char in
let isColon = char == ":"
let cellWidth = isColon ? colonCellWidth : digitCellWidth
GlassDigitCell(character: String(char), font: ctFont,
cellWidth: cellWidth, cellHeight: cellHeight)
}
}
Die Zellen sind nicht Apple-Standard; sie sind ein Workaround für proportionalbreites Rendering bei kleinen, festen Schriftgrößen. Apples SF Pro Rounded mit .monospacedDigit() würde dasselbe Problem auf Text lösen, aber der Modifier ist auf einem eigenen, Shape-basierten Glas-Renderer nicht verfügbar. Das Layout mit festen Zellen ist der Ersatz.
Override der Layout-Richtung auf tvOS. Dasselbe GlassTimerText lief auf iOS, iPadOS, macOS und tvOS. Speziell auf tvOS spiegelte sich das HStack unter einer Rechts-nach-Links-Sprachumgebung, obwohl die iOS-Version den In-Environment-Override respektierte. Die Lösung: die Layout-Richtung sowohl über den Environment-Wert als auch über den expliziten Modifier flipsForRightToLeftLayoutDirection(false) festzurren, direkt angewendet auf das HStack der Ziffern-Zellen (das übergeordnete VStack wendet den Environment-Override separat an, damit die Reflexions-Kopie ihn erbt):6
HStack(spacing: 0) { ... }
.flipsForRightToLeftLayoutDirection(false)
.environment(\.layoutDirection, .leftToRight)
Der Grund: Das HStack von tvOS scheint den Override auf Environment-Ebene in manchen Versionen zu ignorieren, und flipsForRightToLeftLayoutDirection(false) ist der explizite Kein-Spiegeln-Vertrag, der zuverlässiger respektiert wird.12 Doppelt hält besser.
Reduzierte Bewegung beim Ziffern-Morphing. Liquid Glass animiert Morph-Übergänge zwischen angezeigten Strings standardmäßig. Nutzer mit aktiviertem accessibilityReduceMotion sahen das Morphing als Flackern. Die Lösung:6
.animation(reduceMotion ? nil : .easeInOut(duration: 0.15), value: displayTime)
Der Animations-Modifier liest @Environment(\.accessibilityReduceMotion) und deaktiviert den Übergang vollständig, wenn reduzierte Bewegung aktiv ist. Apples Barrierefreiheits-Leitlinie ist eindeutig: Jede dekorative Animation muss die Bewegungs-Präferenz des Nutzers respektieren.7
Wann Liquid Glass nicht zu verwenden ist
Verzicht ist Teil des Designs.
Setzen Sie Liquid Glass nicht in die Inhalts-Schicht. Apples HIG ist eindeutig, und die Regel zu ignorieren erzeugt eine verwirrende Hierarchie: Der Nutzer kann nicht erkennen, was interaktiv und was Inhalt ist.3 Wenn ein Glaseffekt eine Listenzeile oder eine Fotokarte schmückt, kämpft das Design gegen die Plattform.
Verwenden Sie kein Glas über einem flachen Hintergrund. Liquid Glass bricht das, was hinter ihm liegt. Wenn „das, was hinter ihm liegt” eine einzelne Vollfarbe ist, hat die Brechung nichts zu beugen, und das Ergebnis wirkt wie ein flaches, getöntes Rechteck. Setzen Sie Glas entweder über abwechslungsreichen Inhalt (einen Verlauf, ein Bild, ein Video) oder verwenden Sie überhaupt kein Glas. Der Timer-Bildschirm von Return zeigt themenbasierte Cover-Bildwelten und gelooptes Video als Hintergrund über VideoBackgroundView,4 gerade damit die Glaselemente darüber stets Textur zum Brechen haben.
Seien Sie vorsichtig mit Glas auf hochfrequentem Inhalt. Das Rendern des Glasmaterials ist GPU-gebunden, und die standardmäßige Morph-Animation zwischen Glas-Formänderungen ist selbst eine Animation. Ein Timer, der sich einmal pro Sekunde aktualisiert, ist in meinen Tests in Ordnung; ein Wellenform- oder Audio-Visualizer mit 60 Hz ist unerprobt und kämpft wahrscheinlich mit der Morph-Animation. Ich habe die Obergrenze nicht gemessen; behandeln Sie dies als Faustregel, nicht als gemessenen Schwellenwert. Apples Dokumentation veröffentlicht keinen.
Liefern Sie kein Glas aus, ohne reduzierte Bewegung zu testen. Jede Glas-Animation sollte an accessibilityReduceMotion gekoppelt sein.7 Das standardmäßige Morphing zwischen Glas-Formen ist ein kinetischer Effekt, nicht nur eine Überblendung.
Was Liquid Glass für Apps bedeutet, die ab iOS 26 ausgeliefert werden
Die These ist klein. Liquid Glass ist nur dann eine einzeilige API, wenn die App die HIG-Schichtungsregel bereits respektiert. Eine SwiftUI-App, die Bedienelemente in die funktionale Schicht und Inhalt in die Inhalts-Schicht legt, kann Liquid Glass mit .glassEffect()-Modifiern übernehmen und sich standardmäßig nativ anfühlen.
Apps, die die beiden Schichten vermischen (Bedienelemente in Listenzeilen, Navigationsleisten als Inhalt behandelt, dekoratives Chrom auf Fotokarten), werden Liquid Glass übernehmen und sich falsch anfühlen. Das Material ist korrekt; die Architektur darunter ist es nicht.
Das Muster der eigenen Shape (Muster 1) erweitert die Regel sauber. Alles, was funktional ein Bedienelement ist, kann Liquid Glass annehmen, selbst wenn es im herkömmlichen Sinn nicht wie ein „Bedienelement” aussieht. Ein Timer ist ein Bedienelement, ein Pegelmesser ist ein Bedienelement, ein Fortschrittsindikator ist ein Bedienelement. Liquid Glass auf jedem davon ist spezifikationskonform.
Kombinieren Sie diesen Beitrag mit meinen früheren Texten über das Ausliefern der Datenschicht derselben App über App Intents und über einen MCP-Server. Die visuelle Schicht ist die dritte Oberfläche desselben Stacks: typisierte Entities für die System-KI, ein Dateiformat für LLM-übergreifende Agents und Liquid Glass für den Menschen am Gerät.8
FAQ
Kann ich .glassEffect() auf Plattformen vor iOS 26 verwenden?
Der Modifier .glassEffect() ist iOS 26+, iPadOS 26+, macOS 26+, watchOS 26+, tvOS 26+, visionOS 26+. Plattformen vor 26 haben .background(.regularMaterial) und Ähnliches, die Milchglas-Effekte erzeugen, aber nicht die neue Liquid-Glass-Brechung.1
Verändert GlassEffectContainer die Darstellung?
Container-umschlossene Glaselemente können ihre Formen miteinander verschmelzen, wenn ihre Abstandsregeln eine Überlappung verursachen. Ohne Container ist jedes .glassEffect() eigenständig. Für Apps, in denen Glaselemente während einer Animation fließend verschmelzen sollen, ist GlassEffectContainer das richtige Werkzeug. Für Apps, in denen jedes Glaselement eigenständig bleibt, ist ein Container Overhead.1
Warum nicht Text direkt mit .foregroundStyle(.thinMaterial) verwenden?
thinMaterial ist ein Standard-Material, kein Liquid Glass. Die Darstellung ist ein Milchglas-Overlay, nicht der brechende Glas-mit-Lichtbeugung-Effekt von Liquid Glass.3 Für Text, der speziell wie das neue Material aussehen soll, ist .glassEffect(.clear, in: customShape) der unterstützte Weg.
Wie erstelle ich einen Screenshot von Liquid Glass für Marketing?
Glaseffekte werden zur Laufzeit auf der GPU gerendert, daher werden Screenshots vom Simulator oder Gerät mit bereits angewendetem Effekt aufgenommen. Apples offizielles Liquid-Glass-Referenzmaterial stammt von ihren HIG-Dokumentationsseiten und den WWDC-2025-Sessions.3
Funktioniert GlassTextShape für beliebigen Text oder nur für Ziffern?
Jeder String, den Core Text setzen kann, funktioniert. Return nutzt es für Ziffern und einen Doppelpunkt, aber dieselbe Shape funktioniert für Buchstaben, Symbole, Emojis (mit der passenden Schrift) oder gemischte Strings. Die Performance ist durch die Glyphen-Anzahl begrenzt; ein langer Absatz, der als Glas gerendert wird, wäre teuer, aber ein sechsstelliger Timer ist trivial.
Drei Muster, eine Regel und eine API, die ich bewusst übersprungen habe. Liquid Glass ist die dritte Oberfläche einer App ab iOS 26, die auf typisierten Entities und geteilten Dateiformaten aufsitzt. Die einzeilige API ist real. Die HIG-Regel darunter ist es, die den Einzeiler funktionieren lässt.
References
-
Apple Developer, “Applying Liquid Glass to custom views”. Documentation for the
glassEffect(_:in:)modifier,GlassEffectContainer,glassEffectUnion(id:namespace:),glassEffectID(_:in:), andGlassEffectTransition. Default variant.regular, default shapeCapsule. ↩↩↩↩↩↩↩↩↩↩ -
Author’s Return, a meditation-timer app published on the App Store on April 21, 2026, available for iPhone, iPad, Mac, Apple Watch, and Apple TV. Uses SwiftUI, SwiftData, and HealthKit on iOS 26+ / macOS 26+. ↩
-
Apple Developer, “Materials” Human Interface Guidelines. Defines the functional vs content layer rule for Liquid Glass: “Don’t use Liquid Glass in the content layer.” Lists the regular and clear variants and their intended uses. ↩↩↩↩↩↩↩↩↩↩↩↩↩
-
Production code in
Return/Return/ContentView.swift(seven.glassEffect()call sites),Return/Return/GlassTimerText.swift(one call site onGlassDigitCell), andReturn/ReturnTV/TVContentView.swift(one call site on the tvOS “Paused” indicator). Total nine. PlusReturn/Return/VideoBackgroundView.swift, which renders the theme-based cover imagery and looped video that the glass elements refract through. ↩↩↩↩ -
Production code in
Return/Return/GlassTextShape.swift. TheShape-conforming wrapper around Core Text. Created November 26, 2025, included in shipped App Store v1.0. ↩↩ -
Production code in
Return/Return/GlassTimerText.swift.GlassDigitCell,GlassTimerText, andGlassTimerDisplayviews. Implements fixed-width cell layout, the mirror reflection, and reduce-motion gating. ↩↩↩↩↩↩↩ -
Apple Developer, “accessibilityReduceMotion” environment value. Apps must honor the user’s motion preference; default morph animations on Liquid Glass should be gated on the value. ↩↩↩
-
Author’s analysis in App Intents Are Apple’s New API to Your App and Two Agent Ecosystems, One Shopping List. The three-surface model: App Intents for Apple Intelligence, MCP for cross-LLM agents, Liquid Glass for the human at the device. ↩
-
Apple Developer, “glassEffect(_:in:isEnabled:)” on
View. Thein:parameter accepts anyShape-conforming type. The default shape isCapsule. ↩ -
Apple Developer, “Shape” protocol. A
Shapeis any type that produces aPathfor a given rectangle. Custom shapes can wrap arbitraryCGPathdata. ↩ -
Apple Developer, “Core Text Programming Guide” and
CTLineCreateWithAttributedString. Core Text is the lower-level text engine used to lay out attributed strings into glyph runs and extract per-glyph paths. ↩ -
Apple Developer, “flipsForRightToLeftLayoutDirection(_:)”. Explicitly overrides RTL mirroring on a
Viewregardless of the surrounding\.layoutDirectionenvironment value. ↩ -
Apple, “WWDC 2025 Highlights” via Apple Newsroom. Liquid Glass announced as the unifying design material across iOS 26, iPadOS 26, macOS 26, watchOS 26, tvOS 26, and visionOS 26. Sessions: “Meet Liquid Glass” (WWDC 2025), “Build a SwiftUI app with Liquid Glass”. ↩
-
Apple Developer, “LinearGradient”, “scaleEffect(x:y:anchor:)”, “mask(_:)”. Standard SwiftUI primitives, all available since iOS 13. ↩
-
Apple, WWDC 2026 SwiftUI Group Lab (session 2). Paraphrased from a locally transcribed recording of the WWDC 2026 SwiftUI Group Lab (session 2); Apple publishes no official captions for the labs. Source for hiding a toolbar item’s shared glass background to show non-glass content (a profile photo), the newer API that removes only a toolbar button’s content margin rather than the background and margin together, the preference for the prominent glass button style and
buttonBorderShapeover.glassEffecton a button, and the chrome-not-content layering rationale. The supporting symbols are documented atsharedBackgroundVisibility(_:)onCustomizableToolbarContent, which takes aVisibilityvalue such as.hidden, andbuttonBorderShape(_:);glassProminentis the prominent Liquid GlassPrimitiveButtonStyle. The specific content-margin API named in the lab could not be confirmed against Apple’s published documentation, so it is described by behavior rather than asserted by symbol. ↩↩