swiftui-liquid-glass by dpearson2699/swift-ios-skills
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill swiftui-liquid-glassLiquid Glass 是 iOS 26(以及 iPadOS 26、macOS 26、tvOS 26、watchOS 26)中引入的动态半透明材质。它会模糊其后的内容,反射周围的颜色和光线,并对触摸和指针交互做出反应。使用 iOS 26 SDK 构建时,标准 SwiftUI 组件(标签栏、工具栏、导航栏、表单)会自动采用 Liquid Glass。对于自定义视图和控件,请使用下面的 API。
完整的 API 参考及更多示例,请参阅 references/liquid-glass.md。
根据需求选择相应的路径:
GlassEffectContainer 中。.glassEffect()。.interactive()。glassEffectID(_:in:) 添加变形过渡。广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
if #available(iOS 26, *) 进行条件判断,并为早期版本提供回退方案。.glassEffect() 替换的自定义模糊/材质背景。GlassEffectContainer 中,以实现混合和性能优化。.buttonStyle(.glass) 或 .buttonStyle(.glassProminent)。运行下面的审查清单并验证每一项。
在视图后面应用 Liquid Glass。默认值:在 Capsule 形状中使用 .regular 变体。
nonisolated func glassEffect(
_ glass: Glass = .regular,
in shape: some Shape = DefaultGlassEffectShape()
) -> some View
| 属性 / 方法 | 用途 |
|---|---|
.regular | 标准玻璃材质 |
.clear | 清晰变体(最小色调) |
.identity | 无视觉效果(直通) |
.tint(_:) | 添加颜色色调以增强突出性 |
.interactive(_:) | 对触摸和指针交互做出反应 |
链式调用:.regular.tint(.blue).interactive()
包装多个玻璃视图,以实现共享渲染、混合和变形。
GlassEffectContainer(spacing: 24) {
// 带有 .glassEffect() 的子视图
}
spacing 控制相邻玻璃形状何时开始混合。匹配或超过内部布局间距,以便在动画过渡期间形状合并,但在静止时保持分离。
| 修饰符 | 用途 |
|---|---|
glassEffectID(_:in:) | 在视图层次结构变化期间为变形提供稳定的标识符 |
glassEffectUnion(id:namespace:) | 将多个视图合并为一个玻璃形状 |
glassEffectTransition(_:) | 控制玻璃出现/消失的方式 |
过渡类型:.matchedGeometry(在间距内时的默认值)、.materialize(淡入淡出内容 + 玻璃动画进出)、.identity(无过渡)。
Button("Action") { }
.buttonStyle(.glass) // 标准玻璃按钮
Button("Primary") { }
.buttonStyle(.glassProminent) // 突出玻璃按钮
在构建自定义工具栏和滚动视图时,这些功能与 Liquid Glass 相辅相成:
ScrollView {
content
}
.scrollEdgeEffectStyle(.soft, for: .top) // 在滚动边界配置边缘效果
// 将视图复制到安全区域边缘的镜像副本,并带有模糊效果(例如,在侧边栏下)
content
.backgroundExtensionEffect()
在工具栏项目之间创建视觉分隔:
.toolbar {
ToolbarItem { Button("Edit") { } }
ToolbarSpacer(.fixed)
ToolbarItem { Button("Share") { } }
}
if #available(iOS 26, *) {
Text("Status")
.padding()
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 16))
} else {
Text("Status")
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
}
GlassEffectContainer(spacing: 24) {
HStack(spacing: 24) {
ForEach(tools) { tool in
Image(systemName: tool.icon)
.frame(width: 56, height: 56)
.glassEffect(.regular.interactive())
}
}
}
@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)
}
@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)
}
}
}
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))
}
}
过度使用会分散对内容的注意力。玻璃效果应强调关键的交互元素,而不是装饰所有东西。
// 错误:所有东西都用玻璃效果
VStack {
Text("Title").glassEffect()
Text("Subtitle").glassEffect()
Divider().glassEffect()
Text("Body").glassEffect()
}
// 正确:仅对主要的交互元素使用玻璃效果
VStack {
Text("Title").font(.title)
Text("Subtitle").font(.subheadline)
Divider()
Text("Body")
}
.padding()
.glassEffect()
嵌套容器会导致未定义的渲染行为。
// 错误
GlassEffectContainer {
GlassEffectContainer {
content.glassEffect()
}
}
// 正确:单个容器包装所有玻璃视图
GlassEffectContainer {
content.glassEffect()
}
.interactive() 增加了视觉暗示,表明元素可点击。在装饰性玻璃上使用它会误导用户。
玻璃效果根据最终帧计算其形状。在 padding/frame 之前应用它会产生不正确的边界。
// 错误:在 padding 之前应用玻璃效果
Text("Label").glassEffect().padding()
// 正确:在布局之后应用玻璃效果
Text("Label").padding().glassEffect()
始终在启用"降低透明度"和"减弱动态效果"的情况下进行测试。玻璃效果会优雅降级,但需验证内容是否仍可读。
Liquid Glass 需要 iOS 26+。使用 if #available(iOS 26, *) 进行条件判断,并提供回退方案。
if #available(iOS 26, *) 并提供回退 UI。GlassEffectContainer 中。.glassEffect() 在布局/外观修饰符之后应用。.interactive() 仅在有用户交互的地方使用。glassEffectID 与 @Namespace 一起用于变形动画。.matchedGeometry;远处效果使用 .materialize。.glass / .glassProminent。references/liquid-glass.md每周安装量
388
代码仓库
GitHub 星标数
269
首次出现
2026年3月3日
安全审计
安装于
codex385
kimi-cli382
gemini-cli382
cursor382
amp382
cline382
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.
Choose the path that matches the request:
GlassEffectContainer..glassEffect() after layout and appearance modifiers..interactive() only to tappable/focusable elements.glassEffectID(_:in:) where the view hierarchy changes with animation.if #available(iOS 26, *) and provide a fallback for earlier versions..glassEffect().GlassEffectContainer for blending and performance..buttonStyle(.glass) or .buttonStyle(.glassProminent).Run through the Review Checklist below and verify each item.
Applies Liquid Glass behind a view. Default: .regular variant in a Capsule shape.
nonisolated func glassEffect(
_ glass: Glass = .regular,
in shape: some Shape = DefaultGlassEffectShape()
) -> some View
| Property / Method | Purpose |
|---|---|
.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()
Wraps multiple glass views for shared rendering, blending, and morphing.
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.
| Modifier | Purpose |
|---|---|
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).
Button("Action") { }
.buttonStyle(.glass) // standard glass button
Button("Primary") { }
.buttonStyle(.glassProminent) // prominent glass button
These complement Liquid Glass when building custom toolbars and scroll views:
ScrollView {
content
}
.scrollEdgeEffectStyle(.soft, for: .top) // Configures edge effect at scroll boundaries
// Duplicate view into mirrored copies at safe area edges with blur (e.g., under sidebars)
content
.backgroundExtensionEffect()
Creates a visual break between items in toolbars:
.toolbar {
ToolbarItem { Button("Edit") { } }
ToolbarSpacer(.fixed)
ToolbarItem { Button("Share") { } }
}
if #available(iOS 26, *) {
Text("Status")
.padding()
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 16))
} else {
Text("Status")
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
}
GlassEffectContainer(spacing: 24) {
HStack(spacing: 24) {
ForEach(tools) { tool in
Image(systemName: tool.icon)
.frame(width: 56, height: 56)
.glassEffect(.regular.interactive())
}
}
}
@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)
}
@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)
}
}
}
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))
}
}
Overuse distracts from content. Glass should emphasize key interactive elements, not decorate everything.
// WRONG: Glass on everything
VStack {
Text("Title").glassEffect()
Text("Subtitle").glassEffect()
Divider().glassEffect()
Text("Body").glassEffect()
}
// CORRECT: Glass on primary interactive elements only
VStack {
Text("Title").font(.title)
Text("Subtitle").font(.subheadline)
Divider()
Text("Body")
}
.padding()
.glassEffect()
Nested containers cause undefined rendering behavior.
// WRONG
GlassEffectContainer {
GlassEffectContainer {
content.glassEffect()
}
}
// CORRECT: Single container wrapping all glass views
GlassEffectContainer {
content.glassEffect()
}
.interactive() adds visual affordance suggesting tappability. Using it on decorative glass misleads users.
Glass calculates its shape from the final frame. Applying it before padding/frame produces incorrect bounds.
// WRONG: Glass applied before padding
Text("Label").glassEffect().padding()
// CORRECT: Glass applied after layout
Text("Label").padding().glassEffect()
Always test with Reduce Transparency and Reduce Motion enabled. Glass degrades gracefully but verify content remains readable.
Liquid Glass requires iOS 26+. Gate with if #available(iOS 26, *) and provide a fallback.
if #available(iOS 26, *) present with fallback UI.GlassEffectContainer..glassEffect() applied after layout/appearance modifiers..interactive() used only where user interaction exists.glassEffectID used with @Namespace for morphing animations..matchedGeometry for nearby effects; .materialize for distant ones.references/liquid-glass.mdWeekly Installs
388
Repository
GitHub Stars
269
First Seen
Mar 3, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex385
kimi-cli382
gemini-cli382
cursor382
amp382
cline382
Refero Design:研究优先设计方法,学习最佳实践,打造独特用户体验
838 周安装
.glass / .glassProminent used for buttons.