关于 swiftui-liquid-glass
swiftui-liquid-glass 是用于在 SwiftUI 中审查和实现原生 Liquid Glass 界面的技能,涵盖 API 选择、布局模式、可用性检查及常见视觉问题,面向 iOS 26 及更高版本。
主要功能
- 01选择原生玻璃按钮样式
- 02为自定义视图应用玻璃效果
- 03组合相邻的玻璃元素
- 04使用 safeAreaBar 放置底栏
- 05检查工具栏和符号规范
- 06为旧版 iOS 提供回退方案
适用场景
- 01重构自定义模糊玻璃效果
- 02构建玻璃按钮和自定义表面
- 03检查滚动布局中的玻璃效果
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ flowritescode/ fwc-swiftui-skills --skill swiftui-liquid-glass安装后在 Claude Code 中输入/swiftui-liquid-glass确认已加载。
附带文件reference.md
详细介绍
SwiftUI Liquid Glass
在 iOS 26 及更高版本上使用原生 Liquid Glass API。不要用材质、模糊或阴影重新制作这种效果。
核心规则
- 不要通过添加背景、描边、模糊和阴影来制作自定义 Liquid Glass。
- 按钮 — 样式:非彩色按钮使用
.buttonStyle(.glass),着色按钮使用.buttonStyle(.glassProminent)。.glassProminent支持.tint(),但只能使用颜色(不能使用渐变)。 - 按钮 — 形状:使用
.buttonBorderShape(),不要手动为按钮标签应用形状。 - 按钮 — 内边距:这种按钮设置会在 Liquid Glass 形状内部增加约 13pt 的内边距;调整设计时请考虑这一点。
- 自定义视图:使用
.glassEffect(.regular, in: ...)将自定义视图嵌入 Liquid Glass 容器。 - 组合玻璃效果:多个 Liquid Glass 元素相邻时,使用
GlassEffectContainer。当这些元素变大或彼此接触时,此视图 / 容器会产生液态融合效果。 - 滚动:避免在 ScrollView 和 List(任何可滚动内容)中使用 Liquid Glass。
- 底部栏:将 Liquid Glass 视图锚定到屏幕底部时,优先将其嵌入
.safeAreaBar(.bottom),而不是使用 VStack 或.overlay()。safeAreaBar 会在其内容后方添加微妙的模糊效果。 - 工具栏项目 — 不显示玻璃效果:在 iOS 26 及更高版本上,导航栏和窗口工具栏项目默认会共享 Liquid Glass 背景。对于不应显示玻璃胶囊的项目(普通图标、自定义标签、状态文本、徽标),请在
ToolbarItem上应用.sharedBackgroundVisibility(.hidden),而不是应用在内部视图上。 - SF Symbols — 不使用预先包围的符号:不要在 Liquid Glass 按钮或容器中使用预先包围的 SF Symbol 变体(例如
plus.circle、xmark.circle.fill或trash.circle)。玻璃形状本身已充当容器;预先包围的符号会造成别扭的“双层包围”(圆形内又有一个圆形)。请使用基础 / 未包围的符号(plus、xmark、trash),并让.buttonBorderShape()或玻璃容器定义包围形状。
决策树
Need a button?
├─ Neutral / secondary → .buttonStyle(.glass)
└─ Tinted / primary → .buttonStyle(.glassProminent).tint(someColor)
Icon in a glass button / surface?
└─ Plain unenclosed symbol (e.g. "plus", not "plus.circle") — glass provides enclosure
Need a custom non-button surface (chip, badge, card)?
└─ .glassEffect(.regular, in: shape) on the view content
Multiple glass elements nearby?
└─ Wrap in GlassEffectContainer(spacing: ...) { ... }
Fixed bottom toolbar / action bar?
└─ .safeAreaBar(.bottom) { ... } — not VStack + overlay
Toolbar item without glass background?
└─ ToolbarItem { ... }.sharedBackgroundVisibility(.hidden)
Inside ScrollView, List, or Form rows?
└─ Do not use Liquid Glass — use solid/material fallback
工作流
1) 检查现有 UI
- 标记伪装成玻璃效果的自定义模糊 / 材质堆叠。
- 检查按钮是否使用
.glass/.glassProminent,而不是手动构建胶囊形状。 - 确认使用
.buttonBorderShape(),而不是裁剪标签。 - 确认组合元素位于
GlassEffectContainer中。 - 标记可滚动容器中的玻璃效果。
- 检查锚定在底部的栏是否使用
.safeAreaBar(.bottom)。 - 检查应以无玻璃效果方式显示的工具栏项目是否在
ToolbarItem上使用.sharedBackgroundVisibility(.hidden)。 - 标记玻璃按钮或表面中的预先包围的 SF Symbols(例如 circle / square 变体)。
- 使用
#available(iOS 26, *)设置版本检查并提供回退方案。
2) 实现或重构
- 选择合适的原语(按钮样式、
glassEffect或safeAreaBar)。 - 先应用布局和排版;最后添加玻璃效果修饰符。
- 将相邻的玻璃效果元素包装在
GlassEffectContainer中。 - 匹配设计时,考虑约 13pt 的按钮内部内边距。
- 使用未包围的 SF Symbols,让玻璃形状提供包围几何形状。
- 添加 iOS 26 可用性检查和 iOS 26 之前版本的回退方案。
模式
玻璃按钮
// Secondary / neutral
Button("Cancel") { dismiss() }
.buttonStyle(.glass)
.buttonBorderShape(.capsule)
// Primary / tinted — color only, not gradient
Button("Save") { save() }
.buttonStyle(.glassProminent)
.tint(.blue)
.buttonBorderShape(.roundedRectangle(radius: 12))
不要自行裁剪标签:
// ❌ Wrong — shape on label, not the glass button
Button { action() } label: {
Text("Save")
.padding()
.background(.ultraThinMaterial, in: Capsule())
}
// ✅ Right — native glass handles shape and padding
Button("Save") { action() }
.buttonStyle(.glassProminent)
.buttonBorderShape(.capsule)
不要在玻璃按钮中使用预先包围的 SF Symbols:
// ❌ Wrong — pre-enclosed symbol creates redundant double enclosure
Button { add() } label: {
Image(systemName: "plus.circle.fill")
}
.buttonStyle(.glass)
.buttonBorderShape(.circle)
// ✅ Right — plain symbol, glass shape provides the enclosure
Button { add() } label: {
Image(systemName: "plus")
}
.buttonStyle(.glass)
.buttonBorderShape(.circle)
自定义玻璃表面
Label("3 items", systemImage: "tray")
.padding(.horizontal, 16)
.padding(.vertical, 10)
.glassEffect(.regular, in: .capsule)
当表面会响应触摸时,添加 .interactive():
Text("Tap me")
.padding()
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 16))
组合玻璃效果(融合效果)
GlassEffectContainer(spacing: 24) {
HStack(spacing: 24) {
ToolButton(icon: "pencil")
ToolButton(icon: "eraser")
ToolButton(icon: "lasso")
}
}
private struct ToolButton: View {
let icon: String
var body: some View {
Image(systemName: icon)
.frame(width: 56, height: 56)
.font(.title2)
.glassEffect(.regular, in: .circle)
}
}
调整 spacing,控制元素之间的距离要多近才会触发液态融合效果。
底部操作栏
ContentView()
.safeAreaBar(.bottom) {
HStack {
Button("Share") { share() }
.buttonStyle(.glass)
Button("Done") { done() }
.buttonStyle(.glassProminent)
}
}
优先使用此方式,而不是通过 VStack { Spacer(); ... } 或 .overlay(alignment: .bottom) 固定位置。
不带玻璃效果的工具栏项
在 iOS 26 及更高版本中,同一逻辑分组中的工具栏项会共享 Liquid Glass 背景。当某个项应呈现裸露样式时,请将其隐藏:
.toolbar {
ToolbarItem(placement: .principal) {
Text("Draft")
.font(.headline)
}
.sharedBackgroundVisibility(.hidden)
ToolbarItem(placement: .topBarTrailing) {
Button { add() } label: {
Image(systemName: "plus")
}
}
.sharedBackgroundVisibility(.hidden)
ToolbarItem(placement: .topBarTrailing) {
Button("Save") { save() }
.buttonStyle(.glassProminent)
}
}
在 ToolbarItem 上应用 .sharedBackgroundVisibility(.hidden),不要将其应用于内部的 Button 或标签。隐藏该效果会让此项单独分组,因此可能改变它与带玻璃效果的相邻项之间的间距。
不要将此修饰符应用于内部视图:
// ❌ Wrong — modifier on Button, glass background remains
ToolbarItem(placement: .topBarTrailing) {
Button { add() } label: {
Image(systemName: "plus")
}
.sharedBackgroundVisibility(.hidden)
}
// ✅ Right — modifier on ToolbarItem
ToolbarItem(placement: .topBarTrailing) {
Button { add() } label: {
Image(systemName: "plus")
}
}
.sharedBackgroundVisibility(.hidden)
可用性回退
if #available(iOS 26, *) {
content.glassEffect(.regular, in: .rect(cornerRadius: 16))
} else {
content.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
}
反模式
| 反模式 | 失败原因 | 应改用 |
|---|---|---|
.background(.ultraThinMaterial) + 模糊 + 描边 + 阴影 | 不是 Liquid Glass;光学效果不正确,也不会合并或变形 | .glassEffect(...) 或按钮样式 |
在 .glassProminent 上使用渐变 .tint() | API 只接受颜色 | 使用纯色 Color 色调,或使用不带 .glassProminent 色调的自定义标签 |
在 List/ScrollView 行上使用玻璃效果 | 滚动 + 玻璃效果 = 视觉故障和性能开销 | 使用不透明或材质行;玻璃效果仅用于固定界面元素 |
| 将形状应用于按钮标签 | 缺少原生内边距(约 13pt),且边框渲染不正确 | .buttonBorderShape() |
通过 .overlay 创建底部栏 | 不会采用系统的模糊栏样式 | .safeAreaBar(.bottom) |
| 在没有容器的情况下使用多个玻璃视图 | 不会产生合并效果,渲染效果更差 | GlassEffectContainer |
| 在本应不带玻璃效果的工具栏项上使用玻璃胶囊 | iOS 26 默认会为工具栏分组添加共享玻璃效果 | 在 ToolbarItem 上使用 .sharedBackgroundVisibility(.hidden) |
在内部视图上使用 .sharedBackgroundVisibility | 不会移除工具栏玻璃背景 | 应用于 ToolbarItem(或其他 ToolbarContent) |
在玻璃按钮中使用预先带圆形边框的 SF Symbols(plus.circle、xmark.circle.fill) | 重复的双重包围(“圆中有圆”);与玻璃形状冲突 | 使用不带包围形状的符号(plus、xmark),让 .buttonBorderShape 提供容器 |
检查清单
- 没有手工制作的模糊或材质玻璃仿制效果
- 按钮使用
.glass或.glassProminent,并搭配.buttonBorderShape() - 设计间距考虑了约 13pt 的按钮内部内边距
- 自定义表面使用
.glassEffect(.regular, in: ...) - 使用
GlassEffectContainer包裹相邻的玻璃效果 - 滚动视图内没有玻璃效果
- 底部界面元素使用
.safeAreaBar(.bottom) - 不带玻璃效果的工具栏项在
ToolbarItem上使用.sharedBackgroundVisibility(.hidden) - 玻璃按钮中没有预先带包围形状的 SF Symbols(例如,使用 "plus" 而非 "plus.circle")
- 使用
#available(iOS 26, *),并为较旧的 OS 提供回退方案
其他资源
- 详细的 API 说明和变形过渡:reference.md
- 将 Liquid Glass 应用于自定义视图
- Landmarks:使用 Liquid Glass 构建应用
评论
支持 Markdown