| name | liquid-glass-ios |
| description | Implements Liquid Glass design effects in SwiftUI and UIKit. Use when adding glass effects, glass buttons, glass containers, morphing transitions, or adopting Apple Liquid Glass design system. |
Liquid Glass iOS Implementation
Implements Apple's Liquid Glass design system in SwiftUI and UIKit. Liquid Glass is a dynamic material that blurs content behind it, reflects color and light, and reacts to touch/pointer interactions.
When to Use
- Adding glass effects to views or buttons
- Creating glass containers with merging/morphing effects
- Adopting new Apple design language (iOS 26+)
- Building interactive glass elements
- Implementing glass toolbar items
Quick Reference
SwiftUI
Basic Glass Effect
Text("Hello")
.padding()
.glassEffect()
Custom Shape
Text("Hello")
.padding()
.glassEffect(in: .rect(cornerRadius: 16.0))
Shapes: .capsule (default), .rect(cornerRadius:), .circle
Glass Variants
.glassEffect(.regular.tint(.orange).interactive())
.regular — Standard glass
.tint(Color) — Color tint for prominence
.interactive() — Reacts to touch/pointer
Glass Buttons
Button("Action") { }
.buttonStyle(.glass)
Button("Important") { }
.buttonStyle(.glassProminent)
Multiple Glass Elements — Container
Always wrap multiple glass views in GlassEffectContainer:
GlassEffectContainer(spacing: 40.0) {
HStack(spacing: 40.0) {
Image(systemName: "pencil")
.frame(width: 80, height: 80)
.glassEffect()
Image(systemName: "eraser.fill")
.frame(width: 80, height: 80)
.glassEffect()
}
}
spacing controls merge distance between glass elements.
Uniting Glass Effects
Combine views into a single glass effect:
@Namespace private var namespace
GlassEffectContainer(spacing: 20.0) {
HStack(spacing: 20.0) {
ForEach(items.indices, id: \.self) { item in
Image(systemName: items[item])
.frame(width: 80, height: 80)
.glassEffect()
.glassEffectUnion(id: item < 2 ? "1" : "2", namespace: namespace)
}
}
}
Morphing Transitions
@State private var isExpanded = false
@Namespace private var namespace
GlassEffectContainer(spacing: 40.0) {
HStack(spacing: 40.0) {
Image(systemName: "pencil")
.frame(width: 80, height: 80)
.glassEffect()
.glassEffectID("pencil", in: namespace)
if isExpanded {
Image(systemName: "eraser.fill")
.frame(width: 80, height: 80)
.glassEffect()
.glassEffectID("eraser", in: namespace)
}
}
}
Button("Toggle") {
withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)
Toolbar Glass Background
.toolbar(id: "main") {
ToolbarItem(id: "status", placement: .principal) {
StatusView()
}
.sharedBackgroundVisibility(.hidden)
}
Scroll Extension Under Sidebar
ScrollView(.horizontal) {
}
.scrollExtensionMode(.underSidebar)
UIKit
Basic Glass Effect
let glassEffect = UIGlassEffect()
let effectView = UIVisualEffectView(effect: glassEffect)
effectView.layer.cornerRadius = 20
effectView.clipsToBounds = true
view.addSubview(effectView)
Customization
glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3)
glassEffect.isInteractive = true
Glass Container (Multiple Elements)
let containerEffect = UIGlassContainerEffect()
containerEffect.spacing = 40.0
let containerView = UIVisualEffectView(effect: containerEffect)
let glass1 = UIVisualEffectView(effect: UIGlassEffect())
let glass2 = UIVisualEffectView(effect: UIGlassEffect())
containerView.contentView.addSubview(glass1)
containerView.contentView.addSubview(glass2)
Scroll Edge Effects
scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true
Styles: .automatic, .hard
Scroll Edge Element Container Interaction
let interaction = UIScrollEdgeElementContainerInteraction()
interaction.scrollView = scrollView
interaction.edge = .bottom
overlayContainer.addInteraction(interaction)
Toolbar Item Glass
let button = UIBarButtonItem(...)
button.hidesSharedBackground = true
WidgetKit
Rendering Modes
@Environment(\.widgetRenderingMode) var renderingMode
var body: some View {
if renderingMode == .accented {
} else {
}
}
Accent Groups
Text("Title")
.widgetAccentable()
Image("photo")
.widgetAccentedRenderingMode(.monochrome)
Container Background
.containerBackground(for: .widget) {
Color.blue.opacity(0.2)
}
Best Practices
- Always use
GlassEffectContainer for multiple glass views (performance + morphing)
- Apply
.glassEffect() last — after other appearance modifiers
- Use
.interactive() only on elements that respond to user interaction
- Subtle tint colors — avoid opaque tints, use low alpha
- Test on older devices — glass effects are GPU-intensive
- Ensure contrast — text on glass must meet accessibility requirements
- Animate view hierarchy changes — enables smooth morphing transitions
- Consistent shapes — maintain uniform corner radii across the app
Detailed Reference
Read reference/swiftui-liquid-glass.md for full SwiftUI guide with advanced examples.
Read reference/uikit-liquid-glass.md for full UIKit guide with reusable components.
Read reference/widgetkit-liquid-glass.md for widget-specific implementation.
Apple Documentation Links