SkillAgentSearch skills...

LiquidGlassReference

iOS 26 Liquid Glass: Ultimate Swift/SwiftUI Reference. This is really just a document I can point Claude at when I want to make glass. conor.fyi/writing/liquid-glass-reference

Install / Use

/learn @conorluddy/LiquidGlassReference
About this skill

Quality Score

0/100

Supported Platforms

Claude Code
Claude Desktop

README

iOS 26 Liquid Glass: Comprehensive Swift/SwiftUI Reference

https://conor.fyi/writing/liquid-glass-reference

Overview

Screenshot 2025-11-16 at 14 50 09 Medium

iOS 26 Liquid Glass represents Apple's most significant design evolution since iOS 7, introduced at WWDC 2025 (June 9, 2025). Liquid Glass is a translucent, dynamic material that reflects and refracts surrounding content while transforming to bring focus to user tasks. This unified design language spans iOS 26, iPadOS 26, macOS Tahoe 26, watchOS 26, tvOS 26, and visionOS 26.

Liquid Glass features real-time light bending (lensing), specular highlights responding to device motion, adaptive shadows, and interactive behaviors. The material continuously adapts to background content, light conditions, and user interactions, creating depth and hierarchy between foreground controls and background content.

Key Characteristics:

  • Lensing: Bends and concentrates light in real-time (vs. traditional blur that scatters light)
  • Materialization: Elements appear by gradually modulating light bending
  • Fluidity: Gel-like flexibility with instant touch responsiveness
  • Morphing: Dynamic transformation between control states
  • Adaptivity: Multi-layer composition adjusting to content, color scheme, and size

Part 1: Foundation \u0026 Basics

1.1 Core Concepts

Design Philosophy Liquid Glass is exclusively for the navigation layer that floats above app content. Never apply to content itself (lists, tables, media). This maintains clear visual hierarchy: content remains primary while controls provide functional overlay.

Material Variants

| Variant | Use Case | Transparency | Adaptivity | |---------|----------|--------------|------------| | .regular | Default for most UI | Medium | Full - adapts to any content | | .clear | Media-rich backgrounds | High | Limited - requires dimming layer | | .identity | Conditional disable | None | N/A - no effect applied |

When to Use Each Variant:

  • Regular: Toolbars, buttons, navigation bars, tab bars, standard controls
  • Clear: Small floating controls over photos/maps with bold foreground content
  • Identity: Conditional toggling (e.g., glassEffect(isEnabled ? .regular : .identity))

Design Requirements for Clear Variant (all must be met):

  1. Element sits over media-rich content
  2. Content won't be negatively affected by dimming layer
  3. Content above glass is bold and bright

1.2 Basic Implementation

Simple Glass Effect

import SwiftUI

struct BasicGlassView: View {
    var body: some View {
        Text("Hello, Liquid Glass!")
            .padding()
            .glassEffect()  // Default: .regular variant, .capsule shape
    }
}

With Explicit Parameters

Text("Custom Glass")
    .padding()
    .glassEffect(.regular, in: .capsule, isEnabled: true)

API Signature

func glassEffect<S: Shape>(
    _ glass: Glass = .regular,
    in shape: S = DefaultGlassEffectShape,
    isEnabled: Bool = true
) -> some View

1.3 Glass Type Modifiers

Core Structure

struct Glass {
    static var regular: Glass
    static var clear: Glass
    static var identity: Glass
    
    func tint(_ color: Color) -> Glass
    func interactive() -> Glass
}

Tinting

// Basic tint
Text("Tinted")
    .padding()
    .glassEffect(.regular.tint(.blue))

// With opacity
Text("Subtle Tint")
    .padding()
    .glassEffect(.regular.tint(.purple.opacity(0.6)))

Purpose: Convey semantic meaning (primary action, state), NOT decoration. Use selectively for call-to-action only.

Interactive Modifier (iOS only)

Button("Tap Me") { 
    // action
}
.glassEffect(.regular.interactive())

Behaviors Enabled:

  • Scaling on press
  • Bouncing animation
  • Shimmering effect
  • Touch-point illumination that radiates to nearby glass
  • Response to tap and drag gestures

Method Chaining

.glassEffect(.regular.tint(.orange).interactive())
.glassEffect(.clear.interactive().tint(.blue))  // Order doesn't matter

1.4 Custom Shapes

Available Shapes

// Capsule (default)
.glassEffect(.regular, in: .capsule)

// Circle
.glassEffect(.regular, in: .circle)

// Rounded Rectangle
.glassEffect(.regular, in: RoundedRectangle(cornerRadius: 16))

// Container-concentric (aligns with container corners)
.glassEffect(.regular, in: .rect(cornerRadius: .containerConcentric))

// Ellipse
.glassEffect(.regular, in: .ellipse)

// Custom shape conforming to Shape protocol
struct CustomShape: Shape {
    func path(in rect: CGRect) -> Path {
        // Custom path logic
    }
}
.glassEffect(.regular, in: CustomShape())

Corner Concentricity Maintains perfect alignment between elements and containers across devices:

// Automatically matches container/window corners
RoundedRectangle(cornerRadius: .containerConcentric, style: .continuous)

1.5 Text \u0026 Icons with Glass

Text Rendering

Text("Glass Text")
    .font(.title)
    .bold()
    .foregroundStyle(.white)  // High contrast for legibility
    .padding()
    .glassEffect()

Text on glass automatically receives vibrant treatment - adjusts color, brightness, saturation based on background.

Icon Rendering

Image(systemName: "heart.fill")
    .font(.largeTitle)
    .foregroundStyle(.white)
    .frame(width: 60, height: 60)
    .glassEffect(.regular.interactive())

Labels

Label("Settings", systemImage: "gear")
    .labelStyle(.iconOnly)
    .padding()
    .glassEffect()

1.6 Accessibility Support

Automatic Adaptation - No code changes required:

  • Reduced Transparency: Increases frosting for clarity
  • Increased Contrast: Stark colors and borders
  • Reduced Motion: Tones down animations and elastic effects
  • iOS 26.1+ Tinted Mode: User-controlled opacity increase (Settings → Display & Brightness → Liquid Glass)

Environment Values

@Environment(\.accessibilityReduceTransparency) var reduceTransparency
@Environment(\.accessibilityReduceMotion) var reduceMotion

var body: some View {
    Text("Accessible")
        .padding()
        .glassEffect(reduceTransparency ? .identity : .regular)
}

Best Practice: Let system handle accessibility automatically. Don't override unless absolutely necessary.


Part 2: Intermediate Techniques

2.1 GlassEffectContainer

Purpose

  • Combines multiple Liquid Glass shapes into unified composition
  • Improves rendering performance by sharing sampling region
  • Enables morphing transitions between glass elements
  • Critical Rule: Glass cannot sample other glass; container provides shared sampling region

Basic Usage

GlassEffectContainer {
    HStack(spacing: 20) {
        Image(systemName: "pencil")
            .frame(width: 44, height: 44)
            .glassEffect(.regular.interactive())
        
        Image(systemName: "eraser")
            .frame(width: 44, height: 44)
            .glassEffect(.regular.interactive())
    }
}

With Spacing Control

GlassEffectContainer(spacing: 40.0) {
    // Glass elements within 40 points will morph together
    ForEach(icons) { icon in
        IconView(icon)
            .glassEffect()
    }
}

Spacing Parameter: Controls morphing threshold - elements within this distance visually blend and morph together during transitions.

API Signature

struct GlassEffectContainer<Content: View>: View {
    init(spacing: CGFloat? = nil, @ViewBuilder content: () -> Content)
    init(@ViewBuilder content: () -> Content)
}

2.2 Morphing Transitions with glassEffectID

Requirements for Morphing:

  1. Elements in same GlassEffectContainer
  2. Each view has glassEffectID with shared namespace
  3. Views conditionally shown/hidden trigger morphing
  4. Animation applied to state changes

Basic Morphing Setup

struct MorphingExample: View {
    @State private var isExpanded = false
    @Namespace private var namespace
    
    var body: some View {
        GlassEffectContainer(spacing: 30) {
            Button(isExpanded ? "Collapse" : "Expand") {
                withAnimation(.bouncy) {
                    isExpanded.toggle()
                }
            }
            .glassEffect()
            .glassEffectID("toggle", in: namespace)
            
            if isExpanded {
                Button("Action 1") { }
                    .glassEffect()
                    .glassEffectID("action1", in: namespace)
                
                Button("Action 2") { }
                    .glassEffect()
                    .glassEffectID("action2", in: namespace)
            }
        }
    }
}

API Signature

func glassEffectID<ID: Hashable>(
    _ id: ID,
    in namespace: Namespace.ID
) -> some View

Advanced Morphing Pattern - Expandable Action Menu

struct ActionButtonsView: View {
    @State private var showActions = false
    @Namespace private var namespace
    
    var body: some View {
        ZStack {
            Image("background")
                .resizable()
                .ignoresSafeArea()
            
            GlassEffectContainer(spacing: 30) {
                VStack(spacing: 30) {
                    // Top button
                    if showActions {
                        actionButton("rotate.right")
                            .glassEffectID("rotate", in: namespace)
                    }
                    
                    HStack(spacing: 30) {
                        // Left button
                        if showActions {
                            actionButton("circle.lefthalf.filled")
                                .glassEffectID("contrast", in: namespace)
                        }
                        
                        // Toggle (always visible
View on GitHub
GitHub Stars231
CategoryContent
Updated40m ago
Forks16

Security Score

85/100

Audited on Mar 31, 2026

No findings