liquid-glass

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Liquid Glass Design System for Apple Platforms

Apple平台的Liquid Glass设计系统

Build and migrate SwiftUI apps using Apple's Liquid Glass design language introduced at WWDC 2025. This skill covers iOS 26, iPadOS 26, macOS 26 (Tahoe), watchOS 26, tvOS 26, and visionOS 26.
使用Apple在WWDC 2025上推出的Liquid Glass设计语言构建和迁移SwiftUI应用。本技能涵盖iOS 26、iPadOS 26、macOS 26(Tahoe)、watchOS 26、tvOS 26和visionOS 26。

Important: Use Latest Documentation

重要提示:使用最新文档

Always fetch the latest Apple developer documentation when implementing Liquid Glass features. The APIs may evolve between OS betas. Key documentation URLs to reference:
  • https://developer.apple.com/documentation/SwiftUI/Applying-Liquid-Glass-to-custom-views
  • https://developer.apple.com/documentation/swiftui/view/glasseffect(_:in:)
  • https://developer.apple.com/documentation/SwiftUI/Landmarks-Building-an-app-with-Liquid-Glass
  • https://developer.apple.com/videos/play/wwdc2025/323/
    (WWDC25 Session: Build a SwiftUI app with the new design)
在实现Liquid Glass功能时,请始终获取最新的Apple开发者文档。API可能会在OS测试版之间迭代。需参考的关键文档链接:
  • https://developer.apple.com/documentation/SwiftUI/Applying-Liquid-Glass-to-custom-views
  • https://developer.apple.com/documentation/swiftui/view/glasseffect(_:in:)
  • https://developer.apple.com/documentation/SwiftUI/Landmarks-Building-an-app-with-Liquid-Glass
  • https://developer.apple.com/videos/play/wwdc2025/323/
    (WWDC25 Session: Build a SwiftUI app with the new design)

Core Concept

核心概念

Liquid Glass is a translucent, dynamic material exclusively for the navigation layer (toolbars, tab bars, buttons, controls) that floats above app content. It bends and refracts light in real-time, responds to device motion with specular highlights, and adapts continuously to background content.
Never apply glass to content itself (lists, tables, media, text blocks). Glass is for controls and navigation only.
Liquid Glass是一种半透明的动态材质,专门用于导航层(工具栏、标签栏、按钮、控件),悬浮在应用内容上方。它能实时折射光线,随设备运动产生镜面高光,并持续适配背景内容。
切勿将玻璃效果应用于内容本身(列表、表格、媒体、文本块)。玻璃效果仅适用于控件和导航元素。

Quick Start: Key APIs

快速入门:核心API

1. Glass Effect on Custom Views

1. 自定义视图的玻璃效果

swift
// Basic - capsule shape (default)
Text("Label")
    .padding()
    .glassEffect()

// With shape and style
Image(systemName: "heart.fill")
    .padding()
    .glassEffect(.regular, in: .rect(cornerRadius: 16))

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

// Interactive glass (scales, bounces, shimmers on touch - iOS only)
Button("Tap Me") { }
    .glassEffect(.regular.interactive())
swift
// 基础用法 - 胶囊形状(默认)
Text("Label")
    .padding()
    .glassEffect()

// 指定形状和样式
Image(systemName: "heart.fill")
    .padding()
    .glassEffect(.regular, in: .rect(cornerRadius: 16))

// 着色玻璃效果
Text("Tinted")
    .padding()
    .glassEffect(.regular.tint(.blue))

// 交互式玻璃效果(触摸时缩放、弹跳、闪烁 - 仅iOS支持)
Button("Tap Me") { }
    .glassEffect(.regular.interactive())

2. Glass Styles

2. 玻璃样式

StyleUse CaseTransparency
.regular
Standard UI: toolbars, buttons, nav barsMedium
.clear
Media-rich backgrounds where content is bold/brightHigh
.identity
Conditionally disable glass (accessibility)None
样式使用场景透明度
.regular
标准UI:工具栏、按钮、导航栏中等
.clear
媒体丰富的背景,内容醒目/明亮
.identity
有条件地禁用玻璃效果(无障碍适配)

3. GlassEffectContainer (Critical)

3. GlassEffectContainer(关键组件)

Glass cannot sample other glass. Nearby glass elements MUST share a container for visual consistency and morphing.
swift
GlassEffectContainer(spacing: 30.0) {
    Button("Action 1") { }
        .glassEffect()
        .glassEffectID("btn1", in: namespace)

    Button("Action 2") { }
        .glassEffect()
        .glassEffectID("btn2", in: namespace)
}
玻璃效果无法采样其他玻璃元素。相邻的玻璃元素必须共享一个容器,以保证视觉一致性和形态过渡效果。
swift
GlassEffectContainer(spacing: 30.0) {
    Button("Action 1") { }
        .glassEffect()
        .glassEffectID("btn1", in: namespace)

    Button("Action 2") { }
        .glassEffect()
        .glassEffectID("btn2", in: namespace)
}

4. Morphing Transitions

4. 形态过渡动画

Use
@Namespace
+
glassEffectID
inside a
GlassEffectContainer
for smooth glass morphing:
swift
@Namespace private var namespace
@State private var isExpanded = false

GlassEffectContainer(spacing: 16) {
    if isExpanded {
        ForEach(items) { item in
            ItemView(item: item)
                .glassEffect(.regular, in: .rect(cornerRadius: 24))
                .glassEffectID(item.id, in: namespace)
        }
    }
    Button {
        withAnimation { isExpanded.toggle() }
    } label: { Label("Toggle", systemImage: "chevron.down") }
    .buttonStyle(.glass)
    .glassEffectID("toggle", in: namespace)
}
GlassEffectContainer
内结合
@Namespace
glassEffectID
实现流畅的玻璃形态过渡:
swift
@Namespace private var namespace
@State private var isExpanded = false

GlassEffectContainer(spacing: 16) {
    if isExpanded {
        ForEach(items) { item in
            ItemView(item: item)
                .glassEffect(.regular, in: .rect(cornerRadius: 24))
                .glassEffectID(item.id, in: namespace)
        }
    }
    Button {
        withAnimation { isExpanded.toggle() }
    } label: { Label("Toggle", systemImage: "chevron.down") }
    .buttonStyle(.glass)
    .glassEffectID("toggle", in: namespace)
}

5. Background Extension Effect

5. 背景扩展效果

Extends and blurs visual content behind navigation elements (toolbars, sidebars, inspectors):
swift
Image(landmark.backgroundImageName)
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
    .backgroundExtensionEffect()
将导航元素(工具栏、侧边栏、检查器)后方的视觉内容进行扩展和模糊:
swift
Image(landmark.backgroundImageName)
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
    .backgroundExtensionEffect()

6. Glass Buttons

6. 玻璃按钮

swift
// Standard glass button
Button("Action") { }
    .buttonStyle(.glass)

// Prominent glass button (for primary actions)
Button("Save") { }
    .buttonStyle(.glassProminent)
swift
// 标准玻璃按钮
Button("Action") { }
    .buttonStyle(.glass)

// 突出显示的玻璃按钮(用于主要操作)
Button("Save") { }
    .buttonStyle(.glassProminent)

7. Toolbars with Glass

7. 带玻璃效果的工具栏

Toolbar items automatically receive glass styling. Use
ToolbarSpacer
and
ToolbarItemGroup
for layout:
swift
.toolbar {
    ToolbarSpacer(.flexible)
    ToolbarItem { ShareLink(item: data, preview: preview) }
    ToolbarSpacer(.fixed)
    ToolbarItemGroup {
        Button("Favorite", systemImage: "heart") { }
        Button("Add", systemImage: "plus") { }
    }
    ToolbarItem {
        Button("Info", systemImage: "info") { }
    }
}
.toolbar(removing: .title) // Remove title for clean glass toolbar
工具栏项会自动应用玻璃样式。使用
ToolbarSpacer
ToolbarItemGroup
进行布局:
swift
.toolbar {
    ToolbarSpacer(.flexible)
    ToolbarItem { ShareLink(item: data, preview: preview) }
    ToolbarSpacer(.fixed)
    ToolbarItemGroup {
        Button("Favorite", systemImage: "heart") { }
        Button("Add", systemImage: "plus") { }
    }
    ToolbarItem {
        Button("Info", systemImage: "info") { }
    }
}
.toolbar(removing: .title) // 移除标题以获得简洁的玻璃工具栏

8. Tab Bars

8. 标签栏

Tab bars automatically adopt glass when compiled with Xcode 26:
swift
TabView {
    Tab("Home", systemImage: "house") { HomeView() }
    Tab("Search", systemImage: "magnifyingglass") { SearchView() }
}
.tabBarMinimizeBehavior(.onScrollDown) // Collapse tab bar on scroll
使用Xcode 26编译时,标签栏会自动采用玻璃效果:
swift
TabView {
    Tab("Home", systemImage: "house") { HomeView() }
    Tab("Search", systemImage: "magnifyingglass") { SearchView() }
}
.tabBarMinimizeBehavior(.onScrollDown) // 向下滚动时折叠标签栏

9. Sheets with Glass

9. 带玻璃效果的表单

Partial-height sheets automatically get Liquid Glass backgrounds:
swift
.sheet(isPresented: $showSheet) {
    SheetContent()
        .presentationDetents([.medium, .large])
    // Do NOT add .presentationBackground() - system handles it
}
部分高度的表单会自动获得Liquid Glass背景:
swift
.sheet(isPresented: $showSheet) {
    SheetContent()
        .presentationDetents([.medium, .large])
    // 请勿添加.presentationBackground() - 系统会自动处理
}

Migration Workflow (Existing Apps)

迁移流程(现有应用)

For detailed migration steps, see references/migration-guide.md.
Summary:
  1. Compile with Xcode 26 SDK - system components auto-adopt glass
  2. Remove custom toolbar backgrounds (
    .toolbarBackground
    )
  3. Replace custom materials on navigation elements with glass modifiers
  4. Wrap grouped glass elements in
    GlassEffectContainer
  5. Add
    .backgroundExtensionEffect()
    to hero images
  6. Update SF Symbol variants (circle variants -> none variants on iOS 26+)
  7. Test accessibility (Reduced Transparency, Increased Contrast, Reduced Motion)
详细迁移步骤请参考references/migration-guide.md
摘要:
  1. 使用Xcode 26 SDK编译 - 系统组件会自动适配玻璃效果
  2. 移除自定义工具栏背景(
    .toolbarBackground
  3. 将导航元素上的自定义材质替换为玻璃修饰符
  4. 将分组的玻璃元素包裹在
    GlassEffectContainer
  5. 为英雄图片添加
    .backgroundExtensionEffect()
  6. 更新SF Symbol变体(iOS 26+上使用无变体替代圆形变体)
  7. 测试无障碍功能(降低透明度、增强对比度、减少动态效果)

Platform Considerations

平台注意事项

For platform-specific details, see references/platform-specifics.md.
Key differences:
  • macOS: Use
    .tint(.clear)
    on glass buttons for proper rendering; use
    WindowBackgroundShapeStyle.windowBackground
    instead of
    Material
    for editing backgrounds
  • iOS (iPhone):
    .interactive()
    works; use
    UIDevice.current.userInterfaceIdiom
    for layout
  • iPadOS: Larger grid sizes; sidebar adaptable tab views
  • Conditional compilation: Use
    #if os(macOS)
    /
    #if os(iOS)
    for platform-specific code
平台特定细节请参考references/platform-specifics.md
核心差异:
  • macOS:玻璃按钮需使用
    .tint(.clear)
    以获得正确渲染;编辑背景使用
    WindowBackgroundShapeStyle.windowBackground
    而非
    Material
  • iOS (iPhone)
    .interactive()
    生效;使用
    UIDevice.current.userInterfaceIdiom
    进行布局适配
  • iPadOS:更大的网格尺寸;侧边栏可适配的标签视图
  • 条件编译:使用
    #if os(macOS)
    /
    #if os(iOS)
    编写平台特定代码

Common Pitfalls

常见陷阱

For detailed pitfalls and solutions, see references/pitfalls-and-solutions.md.
Critical issues:
  • Glass elements outside
    GlassEffectContainer
    produce inconsistent visuals
  • rotationEffect
    on glass views causes shape morphing - bridge to UIKit with
    UIGlassEffect
  • Menu labels with glass cause animation artifacts - use custom
    ButtonStyle
  • Hit-testing only registers on content, not glass area - use
    contentShape()
    to fix
  • Multiple glass effects = multiple
    CABackdropLayer
    instances (3 offscreen textures each) - use containers to group
详细陷阱及解决方案请参考references/pitfalls-and-solutions.md
关键问题:
  • GlassEffectContainer
    外的玻璃元素会导致视觉不一致
  • 玻璃视图上的
    rotationEffect
    会导致形状变形 - 使用
    UIGlassEffect
    桥接至UIKit
  • 带玻璃效果的菜单标签会产生动画伪影 - 使用自定义
    ButtonStyle
  • 点击测试仅识别内容区域,不识别玻璃区域 - 使用
    contentShape()
    修复
  • 多个玻璃效果会生成多个
    CABackdropLayer
    实例(每个实例占用3个离屏纹理)- 使用容器进行分组

Real-World Example Patterns

真实场景示例模式

For complete code patterns from Apple's Landmarks sample app, see examples/landmarks-patterns.md.
Apple Landmarks示例应用的完整代码模式请参考examples/landmarks-patterns.md

Architecture Best Practices

架构最佳实践

  1. NavigationSplitView as app root with glass sidebar
  2. NavigationStack for deep navigation within detail columns
  3. @Observable data model with
    @Environment
    injection
  4. FlexibleHeader pattern: stretching hero images with scroll-linked parallax
  5. .inspector() for supplementary detail panels
  6. .searchable() for global search (auto-styled with glass)
  7. Use
    ToolbarSpacer(.flexible)
    and
    ToolbarSpacer(.fixed)
    for toolbar layout
  8. Prefer symbol-based buttons with text labels in toolbars
  9. Use
    .symbolVariant()
    modifier for SF Symbol state changes
  10. Use
    .symbolEffect(.drawOn)
    for animated icon transitions
  1. 以带玻璃侧边栏的NavigationSplitView作为应用根视图
  2. 使用NavigationStack实现详情列内的深度导航
  3. 采用带
    @Environment
    注入的**@Observable**数据模型
  4. 灵活头部模式:随滚动联动视差的拉伸英雄图片
  5. 使用
    .inspector()
    展示补充详情面板
  6. 使用
    .searchable()
    实现全局搜索(自动应用玻璃样式)
  7. 使用
    ToolbarSpacer(.flexible)
    ToolbarSpacer(.fixed)
    进行工具栏布局
  8. 工具栏中优先使用带文本标签的符号按钮
  9. 使用
    .symbolVariant()
    修饰符实现SF Symbol状态切换
  10. 使用
    .symbolEffect(.drawOn)
    实现图标动画过渡