Was macht Liquid Glass Design System (iOS 26)?
Muster zur Implementierung von Apples Liquid Glass – einem dynamischen Material, das den dahinterliegenden Inhalt unscharf macht, Farbe und Licht der Umgebung reflektiert und auf Berührungs- und Zeigerinteraktionen reagiert. Deckt die Integration in SwiftUI, UIKit und WidgetKit ab.
Wann aktivieren
- Entwickeln oder Aktualisieren von Apps für iOS 26+ mit der neuen Designsprache
- Implementieren von Glasstilen für Buttons, Karten, Symbolleisten oder Container
- Erstellen von morphierenden Übergängen zwischen Glaselementen
- Anwenden von Liquid Glass-Effekten auf Widgets
- Migrieren bestehender Unschärfe-/Materialeffekte zur neuen Liquid Glass API
Kernmuster – SwiftUI
Grundlegender Glaseffekt
Der einfachste Weg, Liquid Glass zu einer beliebigen Ansicht hinzuzufügen:
Text("Hallo, Welt!")
.font(.title)
.padding()
.glassEffect() // Standard: reguläre Variante, Kapselform
Anpassen von Form und Farbton
Text("Hallo, Welt!")
.font(.title)
.padding()
.glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0))
Wichtige Anpassungsoptionen:
.regular– Standard-Glaseffekt.tint(Color)– Farbton für Hervorhebung hinzufügen.interactive()– Reaktion auf Berührungs- und Zeigerinteraktionen- Form:
.capsule(Standard),.rect(cornerRadius:),.circle
Glas-Button-Stile
Button("Klick mich") { /* Aktion */ }
.buttonStyle(.glass)
Button("Wichtig") { /* Aktion */ }
.buttonStyle(.glassProminent)
GlassEffectContainer für mehrere Elemente
Mehrere Glasansichten immer in einem Container für Leistung und Morphen zusammenfassen:
GlassEffectContainer(spacing: 40.0) {
HStack(spacing: 40.0) {
Image(systemName: "scribble.variable")
.frame(width: 80.0, height: 80.0)
.font(.system(size: 36))
.glassEffect()
Image(systemName: "eraser.fill")
.frame(width: 80.0, height: 80.0)
.font(.system(size: 36))
.glassEffect()
}
}
Der Parameter spacing steuert den Verschmelzungsabstand – nähere Elemente verschmelzen ihre Glasformen miteinander.
Vereinigen von Glaseffekten
Mehrere Ansichten mit glassEffectUnion zu einer einzigen Glasform kombinieren:
@Namespace private var namespace
GlassEffectContainer(spacing: 20.0) {
HStack(spacing: 20.0) {
ForEach(symbolSet.indices, id: \.self) { item in
Image(systemName: symbolSet[item])
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectUnion(id: item < 2 ? "group1" : "group2", namespace: namespace)
}
}
}
Morphing-Übergänge
Erstellen Sie sanftes Morphen, wenn Glaselemente erscheinen/verschwinden:
@State private var isExpanded = false
@Namespace private var namespace
GlassEffectContainer(spacing: 40.0) {
HStack(spacing: 40.0) {
Image(systemName: "scribble.variable")
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectID("pencil", in: namespace)
if isExpanded {
Image(systemName: "eraser.fill")
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectID("eraser", in: namespace)
}
}
}
Button("Umschalten") {
withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)
Horizontales Scrollen unter die Seitenleiste verlängern
Damit horizontaler Scroll-Inhalt unter eine Seitenleiste oder einen Inspektor reicht, stellen Sie sicher, dass der ScrollView-Inhalt die linken/rechten Kanten des Containers erreicht. Das System behandelt das Scrollverhalten unter der Seitenleiste automatisch, wenn das Layout bis zu den Kanten reicht – es ist kein zusätzlicher Modifikator erforderlich.
Kernmuster – UIKit
Grundlegendes UIGlassEffect
let glassEffect = UIGlassEffect()
glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3)
glassEffect.isInteractive = true
let visualEffectView = UIVisualEffectView(effect: glassEffect)
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.layer.cornerRadius = 20
visualEffectView.clipsToBounds = true
view.addSubview(visualEffectView)
NSLayoutConstraint.activate([
visualEffectView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
visualEffectView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
visualEffectView.widthAnchor.constraint(equalToConstant: 200),
visualEffectView.heightAnchor.constraint(equalToConstant: 120)
])
// Inhalt zu contentView hinzufügen
let label = UILabel()
label.text = "Liquid Glass"
label.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.contentView.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: visualEffectView.contentView.centerXAnchor),
label.centerYAnchor.constraint(equalTo: visualEffectView.contentView.centerYAnchor)
])
UIGlassContainerEffect für mehrere Elemente
let containerEffect = UIGlassContainerEffect()
containerEffect.spacing = 40.0
let containerView = UIVisualEffectView(effect: containerEffect)
let firstGlass = UIVisualEffectView(effect: UIGlassEffect())
let secondGlass = UIVisualEffectView(effect: UIGlassEffect())
containerView.contentView.addSubview(firstGlass)
containerView.contentView.addSubview(secondGlass)
Scrolleffekte an den Kanten
scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true
Toolbar-Glasintegration
let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
favoriteButton.hidesSharedBackground = true // Vom gemeinsamen Glashintergrund abmelden
Kernmuster – WidgetKit
Erkennung des Darstellungsmodus
struct MyWidgetView: View {
@Environment(\.widgetRenderingMode) var renderingMode
var body: some View {
if renderingMode == .accented {
// Eingefärbter Modus: weiß eingefärbter, thematischer Glashintergrund
} else {
// Vollfarbmodus: Standarddarstellung
}
}
}
Akzentgruppen für visuelle Hierarchie
HStack {
VStack(alignment: .leading) {
Text("Titel")
.widgetAccentable() // Akzentgruppe
Text("Untertitel")
// Primäre Gruppe (Standard)
}
Image(systemName: "star.fill")
.widgetAccentable() // Akzentgruppe
}
Bilddarstellung im akzentuierten Modus
Image("myImage")
.widgetAccentedRenderingMode(.monochrome)
Container-Hintergrund
VStack { /* Inhalt */ }
.containerBackground(for: .widget) {
Color.blue.opacity(0.2)
}
Wichtige Designentscheidungen
| Entscheidung | Begründung |
|---|---|
| GlassEffectContainer-Umhüllung | Leistungsoptimierung, ermöglicht Morphen zwischen Glaselementen |
Parameter spacing | Steuert den Verschmelzungsabstand – Feinabstimmung, wie nah Elemente sein müssen, um zu verschmelzen |
@Namespace + glassEffectID | Ermöglicht sanfte Morphing-Übergänge bei Änderungen der Ansichtshierarchie |
Modifikator interactive() | Explizite Zustimmung für Berührungs-/Zeigerreaktionen – nicht jedes Glas sollte reagieren |
| UIGlassContainerEffect in UIKit | Gleiches Containermuster wie in SwiftUI für Konsistenz |
| Akzentuierter Darstellungsmodus in Widgets | Das System wendet eingefärbtes Glas an, wenn der Benutzer einen eingefärbten Startbildschirm auswählt |
Best Practices
- GlassEffectContainer immer verwenden, wenn Glas auf mehrere Geschwisteransichten angewendet wird – es ermöglicht Morphen und verbessert die Rendering-Leistung
.glassEffect()nach anderen Darstellungsmodifikatoren (frame, font, padding) anwenden.interactive()nur für Elemente verwenden, die auf Benutzerinteraktionen reagieren (Buttons, umschaltbare Elemente)- Abstand in Containern sorgfältig wählen, um zu steuern, wann Glaseffekte verschmelzen
withAnimationverwenden, wenn Ansichtshierarchien geändert werden, um sanfte Morphing-Übergänge zu ermöglichen- Über Darstellungsmodi hinweg testen – Hell-, Dunkel- und akzentuierte/eingefärbte Modi
- Barrierefreiheitskontrast sicherstellen – Text auf Glas muss lesbar bleiben
Zu vermeidende Anti-Patterns
- Mehrere eigenständige
.glassEffect()-Ansichten ohne GlassEffectContainer verwenden - Zu viele Glaseffekte verschachteln – verschlechtert Leistung und visuelle Klarheit
- Glas auf jede Ansicht anwenden – für interaktive Elemente, Symbolleisten und Karten reservieren
clipsToBounds = truein UIKit bei Verwendung von Eckenradien vergessen- Akzentuierten Darstellungsmodus in Widgets ignorieren – unterbricht die eingefärbte Startbildschirm-Darstellung
- Undurchsichtige Hintergründe hinter Glas verwenden – hebt den Transluzenzeffekt auf
Wann verwenden
- Navigationsleisten, Symbolleisten und Tab-Leisten mit dem neuen iOS 26-Design
- Schwebende Aktionsbuttons und kartenartige Container
- Interaktive Steuerelemente, die visuelle Tiefe und Berührungsfeedback benötigen
- Widgets, die in das Liquid-Glass-Erscheinungsbild des Systems integriert werden sollen
- Morphing-Übergänge zwischen zusammenhängenden UI-Zuständen