swiftui-liquid-glass

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SwiftUI Liquid Glass

SwiftUI Liquid Glass

Overview

概述

Liquid Glass is the dynamic translucent material introduced in iOS 26 (and iPadOS 26, macOS 26, tvOS 26, watchOS 26). It blurs content behind it, reflects surrounding color and light, and reacts to touch and pointer interactions. Standard SwiftUI components (tab bars, toolbars, navigation bars, sheets) adopt Liquid Glass automatically when built with the iOS 26 SDK. Use the APIs below for custom views and controls.
See
references/liquid-glass.md
for the full API reference with additional examples.
Liquid Glass是iOS 26(以及iPadOS 26、macOS 26、tvOS 26、watchOS 26)引入的动态半透明材质。它会模糊背后的内容,反射周围的颜色和光线,并响应触摸和指针交互。使用iOS 26 SDK构建时,标准SwiftUI组件(标签栏、工具栏、导航栏、底部弹窗)会自动适配Liquid Glass效果。自定义视图和控件可使用以下API实现。
完整的API参考和更多示例请查看
references/liquid-glass.md

Workflow

工作流程

Choose the path that matches the request:
选择符合需求的路径:

1. Implement a new feature with Liquid Glass

1. 使用Liquid Glass实现新功能

  1. Identify target surfaces (cards, chips, floating controls, custom bars).
  2. Decide shape, prominence, and whether each element needs interactivity.
  3. Wrap grouped glass elements in a
    GlassEffectContainer
    .
  4. Apply
    .glassEffect()
    after layout and appearance modifiers.
  5. Add
    .interactive()
    only to tappable/focusable elements.
  6. Add morphing transitions with
    glassEffectID(_:in:)
    where the view hierarchy changes with animation.
  7. Gate with
    if #available(iOS 26, *)
    and provide a fallback for earlier versions.
  1. 确定目标界面元素(卡片、芯片、悬浮控件、自定义栏)。
  2. 确定每个元素的形状、突出度以及是否需要交互能力。
  3. 将成组的玻璃元素包裹在
    GlassEffectContainer
    中。
  4. 在布局和外观修饰符之后应用
    .glassEffect()
  5. 仅在可点击/可聚焦的元素上添加
    .interactive()
  6. 在视图层级随动画变化的位置,使用
    glassEffectID(_:in:)
    添加变形过渡。
  7. 使用
    if #available(iOS 26, *)
    做版本判断,并为更早版本提供降级方案。

2. Improve an existing feature with Liquid Glass

2. 使用Liquid Glass优化现有功能

  1. Find custom blur/material backgrounds that can be replaced with
    .glassEffect()
    .
  2. Wrap sibling glass elements in
    GlassEffectContainer
    for blending and performance.
  3. Replace custom glass-like buttons with
    .buttonStyle(.glass)
    or
    .buttonStyle(.glassProminent)
    .
  4. Add morphing transitions where animated insertion/removal occurs.
  1. 查找可替换为
    .glassEffect()
    的自定义模糊/材质背景。
  2. 将同级玻璃元素包裹在
    GlassEffectContainer
    中以提升混合效果和性能。
  3. 将自定义类玻璃按钮替换为
    .buttonStyle(.glass)
    .buttonStyle(.glassProminent)
  4. 在有动画插入/移除的位置添加变形过渡。

3. Review existing Liquid Glass usage

3. 审查现有Liquid Glass使用情况

Run through the Review Checklist below and verify each item.
对照下方的审查清单逐一验证每个项目。

Core API Summary

核心API摘要

glassEffect(_:in:)

glassEffect(_:in:)

Applies Liquid Glass behind a view. Default:
.regular
variant in a
Capsule
shape.
swift
func glassEffect(
    _ glass: Glass = .regular,
    in shape: some Shape = DefaultGlassEffectShape()
) -> some View
在视图背后应用Liquid Glass效果。默认配置:
Capsule
形状下的
.regular
变体。
swift
func glassEffect(
    _ glass: Glass = .regular,
    in shape: some Shape = DefaultGlassEffectShape()
) -> some View

Glass struct

Glass结构体

Property / MethodPurpose
.regular
Standard glass material
.clear
Clear variant (minimal tint)
.identity
No visual effect (pass-through)
.tint(_:)
Add a color tint for prominence
.interactive(_:)
React to touch and pointer interactions
Chain them:
.regular.tint(.blue).interactive()
属性 / 方法用途
.regular
标准玻璃材质
.clear
透明变体(最小着色)
.identity
无视觉效果(透传)
.tint(_:)
添加颜色着色提升突出度
.interactive(_:)
响应触摸和指针交互
链式调用示例:
.regular.tint(.blue).interactive()

GlassEffectContainer

GlassEffectContainer

Wraps multiple glass views for shared rendering, blending, and morphing.
swift
GlassEffectContainer(spacing: 24) {
    // child views with .glassEffect()
}
The
spacing
controls when nearby glass shapes begin to blend. Match or exceed the interior layout spacing so shapes merge during animated transitions but remain separate at rest.
包裹多个玻璃视图,实现共享渲染、混合和变形效果。
swift
GlassEffectContainer(spacing: 24) {
    // child views with .glassEffect()
}
spacing
参数控制相邻玻璃形状开始混合的距离。该值应匹配或大于内部布局间距,这样形状在动画过渡时会合并,静止时保持分离。

Morphing & Transitions

变形与过渡

ModifierPurpose
glassEffectID(_:in:)
Stable identity for morphing during view hierarchy changes
glassEffectUnion(id:namespace:)
Merge multiple views into one glass shape
glassEffectTransition(_:)
Control how glass appears/disappears
Transition types:
.matchedGeometry
(default when within spacing),
.materialize
(fade content + animate glass in/out),
.identity
(no transition).
修饰符用途
glassEffectID(_:in:)
视图层级变化时用于变形的稳定标识
glassEffectUnion(id:namespace:)
将多个视图合并为一个玻璃形状
glassEffectTransition(_:)
控制玻璃效果的出现/消失方式
过渡类型:
.matchedGeometry
(间距范围内默认值)、
.materialize
(内容淡入+玻璃效果淡入/淡出)、
.identity
(无过渡)。

Button Styles

按钮样式

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

Button("Primary") { }
    .buttonStyle(.glassProminent)  // prominent glass button
swift
Button("Action") { }
    .buttonStyle(.glass)           // 标准玻璃按钮

Button("Primary") { }
    .buttonStyle(.glassProminent)  // 突出样式玻璃按钮

Scroll Edge Effects and Background Extension (iOS 26+)

滚动边缘效果与背景扩展(iOS 26+)

These complement Liquid Glass when building custom toolbars and scroll views:
swift
ScrollView {
    content
}
.scrollEdgeEffectStyle(.soft, for: .top)  // Fading edge effect at scroll boundaries

// Mirror and blur content at safe area edges (behind glass toolbars)
content
    .backgroundExtensionEffect()
这些API可在构建自定义工具栏和滚动视图时与Liquid Glass搭配使用:
swift
ScrollView {
    content
}
.scrollEdgeEffectStyle(.soft, for: .top)  // 滚动边界的渐变边缘效果

// 在安全区边缘镜像并模糊内容(玻璃工具栏下方)
content
    .backgroundExtensionEffect()

ToolbarSpacer (iOS 26+)

ToolbarSpacer(iOS 26+)

Creates a visual break between items in toolbars containing Liquid Glass:
swift
.toolbar {
    ToolbarItem { Button("Edit") { } }
    ToolbarItem { ToolbarSpacer() }
    ToolbarItem { Button("Share") { } }
}
在包含Liquid Glass的工具栏中创建元素之间的视觉分隔:
swift
.toolbar {
    ToolbarItem { Button("Edit") { } }
    ToolbarItem { ToolbarSpacer() }
    ToolbarItem { Button("Share") { } }
}

Code Examples

代码示例

Basic glass effect with availability gate

带版本可用性判断的基础玻璃效果

swift
if #available(iOS 26, *) {
    Text("Status")
        .padding()
        .glassEffect(.regular.interactive(), in: .rect(cornerRadius: 16))
} else {
    Text("Status")
        .padding()
        .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
}
swift
if #available(iOS 26, *) {
    Text("Status")
        .padding()
        .glassEffect(.regular.interactive(), in: .rect(cornerRadius: 16))
} else {
    Text("Status")
        .padding()
        .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
}

Grouped glass elements in a container

容器中成组的玻璃元素

swift
GlassEffectContainer(spacing: 24) {
    HStack(spacing: 24) {
        ForEach(tools) { tool in
            Image(systemName: tool.icon)
                .frame(width: 56, height: 56)
                .glassEffect(.regular.interactive())
        }
    }
}
swift
GlassEffectContainer(spacing: 24) {
    HStack(spacing: 24) {
        ForEach(tools) { tool in
            Image(systemName: tool.icon)
                .frame(width: 56, height: 56)
                .glassEffect(.regular.interactive())
        }
    }
}

Morphing transition

变形过渡

swift
@State private var isExpanded = false
@Namespace private var ns

var body: some View {
    GlassEffectContainer(spacing: 40) {
        HStack(spacing: 40) {
            Image(systemName: "pencil")
                .frame(width: 80, height: 80)
                .glassEffect()
                .glassEffectID("pencil", in: ns)

            if isExpanded {
                Image(systemName: "eraser.fill")
                    .frame(width: 80, height: 80)
                    .glassEffect()
                    .glassEffectID("eraser", in: ns)
            }
        }
    }

    Button("Toggle") {
        withAnimation { isExpanded.toggle() }
    }
    .buttonStyle(.glass)
}
swift
@State private var isExpanded = false
@Namespace private var ns

var body: some View {
    GlassEffectContainer(spacing: 40) {
        HStack(spacing: 40) {
            Image(systemName: "pencil")
                .frame(width: 80, height: 80)
                .glassEffect()
                .glassEffectID("pencil", in: ns)

            if isExpanded {
                Image(systemName: "eraser.fill")
                    .frame(width: 80, height: 80)
                    .glassEffect()
                    .glassEffectID("eraser", in: ns)
            }
        }
    }

    Button("Toggle") {
        withAnimation { isExpanded.toggle() }
    }
    .buttonStyle(.glass)
}

Unioning views into a single glass shape

将多个视图合并为单个玻璃形状

swift
@Namespace private var ns

GlassEffectContainer(spacing: 20) {
    HStack(spacing: 20) {
        ForEach(items.indices, id: \.self) { i in
            Image(systemName: items[i])
                .frame(width: 80, height: 80)
                .glassEffect()
                .glassEffectUnion(id: i < 2 ? "group1" : "group2", namespace: ns)
        }
    }
}
swift
@Namespace private var ns

GlassEffectContainer(spacing: 20) {
    HStack(spacing: 20) {
        ForEach(items.indices, id: \.self) { i in
            Image(systemName: items[i])
                .frame(width: 80, height: 80)
                .glassEffect()
                .glassEffectUnion(id: i < 2 ? "group1" : "group2", namespace: ns)
        }
    }
}

Tinted glass badge

带着色的玻璃徽章

swift
struct GlassBadge: View {
    let icon: String
    let tint: Color

    var body: some View {
        Image(systemName: icon)
            .font(.title2)
            .padding()
            .glassEffect(.regular.tint(tint), in: .rect(cornerRadius: 12))
    }
}
swift
struct GlassBadge: View {
    let icon: String
    let tint: Color

    var body: some View {
        Image(systemName: icon)
            .font(.title2)
            .padding()
            .glassEffect(.regular.tint(tint), in: .rect(cornerRadius: 12))
    }
}

Do's and Don'ts

正确做法与禁止事项

Do:
  • Use
    GlassEffectContainer
    whenever multiple glass views coexist.
  • Apply
    .glassEffect()
    after layout and appearance modifiers (padding, frame, font).
  • Use
    .interactive()
    only on tappable or focusable elements.
  • Match
    GlassEffectContainer
    spacing with the interior layout spacing.
  • Prefer
    .buttonStyle(.glass)
    /
    .buttonStyle(.glassProminent)
    over manual glass on buttons.
  • Gate with
    if #available(iOS 26, *)
    and provide a non-glass fallback.
  • Use
    withAnimation
    when toggling views that have
    glassEffectID
    for morphing.
Don't:
  • Apply Liquid Glass to every surface -- overuse distracts from content.
  • Nest
    GlassEffectContainer
    inside another
    GlassEffectContainer
    .
  • Add
    .interactive()
    to non-interactive decorative glass.
  • Use custom blur/material overlays when
    .glassEffect()
    can replace them.
  • Hard-code layout metrics that conflict with glass container spacing.
  • Forget to test with Reduce Transparency and Reduce Motion accessibility settings.
正确做法:
  • 存在多个玻璃视图时始终使用
    GlassEffectContainer
  • 在布局和外观修饰符(padding、frame、font)之后应用
    .glassEffect()
  • 仅在可点击或可聚焦的元素上使用
    .interactive()
  • 使
    GlassEffectContainer
    的spacing与内部布局间距匹配。
  • 按钮优先使用
    .buttonStyle(.glass)
    /
    .buttonStyle(.glassProminent)
    ,而非手动添加玻璃效果。
  • 使用
    if #available(iOS 26, *)
    做版本判断,并提供非玻璃效果的降级方案。
  • 切换带有
    glassEffectID
    的视图以实现变形效果时,使用
    withAnimation
    包裹。
禁止事项:
  • 不要在所有界面元素上都应用Liquid Glass——过度使用会分散用户对内容的注意力。
  • 不要在
    GlassEffectContainer
    内部嵌套另一个
    GlassEffectContainer
  • 不要为非交互的装饰性玻璃效果添加
    .interactive()
  • .glassEffect()
    可替代自定义模糊/材质覆盖层时,不要使用自定义实现。
  • 不要硬编码与玻璃容器spacing冲突的布局尺寸。
  • 不要忘记在「降低透明度」和「降低动态效果」无障碍设置下测试。

Review Checklist

审查清单

  • Availability:
    if #available(iOS 26, *)
    present with fallback UI.
  • Container: Multiple glass views wrapped in
    GlassEffectContainer
    .
  • Modifier order:
    .glassEffect()
    applied after layout/appearance modifiers.
  • Interactivity:
    .interactive()
    used only where user interaction exists.
  • Transitions:
    glassEffectID
    used with
    @Namespace
    for morphing animations.
  • Transition type:
    .matchedGeometry
    for nearby effects;
    .materialize
    for distant ones.
  • Consistency: Shapes, tints, and spacing are uniform across related elements.
  • Performance: Glass effects are limited in number; container used for grouping.
  • Accessibility: Tested with Reduce Transparency and Reduce Motion enabled.
  • Button styles: Standard
    .glass
    /
    .glassProminent
    used for buttons.
  • Ensure types driving Liquid Glass effects are Sendable; apply glass effects on @MainActor context
  • 版本可用性:已添加
    if #available(iOS 26, *)
    判断并提供降级UI。
  • 容器使用:多个玻璃视图已包裹在
    GlassEffectContainer
    中。
  • 修饰符顺序
    .glassEffect()
    已在布局/外观修饰符之后应用。
  • 交互性
    .interactive()
    仅应用在存在用户交互的元素上。
  • 过渡效果:变形动画配合
    @Namespace
    使用了
    glassEffectID
  • 过渡类型:邻近效果使用
    .matchedGeometry
    ;远距离效果使用
    .materialize
  • 一致性:相关元素的形状、着色和间距保持统一。
  • 性能:玻璃效果数量有限;已使用容器进行分组。
  • 无障碍:已在「降低透明度」和「降低动态效果」开启的情况下测试。
  • 按钮样式:按钮使用了标准的
    .glass
    /
    .glassProminent
    样式。
  • 确保驱动Liquid Glass效果的类型符合Sendable协议;在@MainActor上下文下应用玻璃效果。

Available MCP Tools

可用MCP工具

  • apple-docs: Use
    fetchAppleDocumentation
    to look up the latest SwiftUI Liquid Glass APIs (e.g., path
    /documentation/SwiftUI/View/glassEffect(_:in:)
    ).
  • xcodebuildmcp: If available, use to build and test your project directly.
  • apple-docs:使用
    fetchAppleDocumentation
    查询最新的SwiftUI Liquid Glass API(例如路径
    /documentation/SwiftUI/View/glassEffect(_:in:)
    )。
  • xcodebuildmcp:如果可用,可用于直接构建和测试你的项目。

References

参考资料