liquid-glass-design by affaan-m/everything-claude-code
npx skills add https://github.com/affaan-m/everything-claude-code --skill liquid-glass-design实现苹果 Liquid Glass 的模式——这是一种动态材质,可模糊其后的内容,反射周围内容的颜色和光线,并对触摸和指针交互做出反应。涵盖 SwiftUI、UIKit 和 WidgetKit 集成。
为任何视图添加 Liquid Glass 的最简单方法:
Text("Hello, World!")
.font(.title)
.padding()
.glassEffect() // 默认:常规变体,胶囊形状
Text("Hello, World!")
.font(.title)
.padding()
.glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0))
关键自定义选项:
.regular — 标准玻璃效果.tint(Color) — 添加颜色色调以突出显示广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
.interactive() — 对触摸和指针交互做出反应.capsule(默认)、.rect(cornerRadius:)、.circleButton("Click Me") { /* action */ }
.buttonStyle(.glass)
Button("Important") { /* action */ }
.buttonStyle(.glassProminent)
为了性能和变形效果,始终将多个玻璃视图包装在一个容器中:
GlassEffectContainer(spacing: 40.0) {
HStack(spacing: 40.0) {
Image(systemName: "scribble.variable")
.frame(width: 80.0, height: 80.0)
.font(.system(size: 36))
.glassEffect()
Image(systemName: "eraser.fill")
.frame(width: 80.0, height: 80.0)
.font(.system(size: 36))
.glassEffect()
}
}
spacing 参数控制合并距离——距离更近的元素会将其玻璃形状融合在一起。
使用 glassEffectUnion 将多个视图合并为单个玻璃形状:
@Namespace private var namespace
GlassEffectContainer(spacing: 20.0) {
HStack(spacing: 20.0) {
ForEach(symbolSet.indices, id: \.self) { item in
Image(systemName: symbolSet[item])
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectUnion(id: item < 2 ? "group1" : "group2", namespace: namespace)
}
}
}
在玻璃元素出现/消失时创建平滑的变形效果:
@State private var isExpanded = false
@Namespace private var namespace
GlassEffectContainer(spacing: 40.0) {
HStack(spacing: 40.0) {
Image(systemName: "scribble.variable")
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectID("pencil", in: namespace)
if isExpanded {
Image(systemName: "eraser.fill")
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectID("eraser", in: namespace)
}
}
}
Button("Toggle") {
withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)
要允许水平滚动内容延伸到侧边栏或检查器下方,请确保 ScrollView 内容到达容器的前缘/后缘。当布局延伸到边缘时,系统会自动处理侧边栏下的滚动行为——无需额外的修饰符。
let glassEffect = UIGlassEffect()
glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3)
glassEffect.isInteractive = true
let visualEffectView = UIVisualEffectView(effect: glassEffect)
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.layer.cornerRadius = 20
visualEffectView.clipsToBounds = true
view.addSubview(visualEffectView)
NSLayoutConstraint.activate([
visualEffectView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
visualEffectView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
visualEffectView.widthAnchor.constraint(equalToConstant: 200),
visualEffectView.heightAnchor.constraint(equalToConstant: 120)
])
// 添加内容到 contentView
let label = UILabel()
label.text = "Liquid Glass"
label.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.contentView.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: visualEffectView.contentView.centerXAnchor),
label.centerYAnchor.constraint(equalTo: visualEffectView.contentView.centerYAnchor)
])
let containerEffect = UIGlassContainerEffect()
containerEffect.spacing = 40.0
let containerView = UIVisualEffectView(effect: containerEffect)
let firstGlass = UIVisualEffectView(effect: UIGlassEffect())
let secondGlass = UIVisualEffectView(effect: UIGlassEffect())
containerView.contentView.addSubview(firstGlass)
containerView.contentView.addSubview(secondGlass)
scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true
let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
favoriteButton.hidesSharedBackground = true // 选择退出共享的玻璃背景
struct MyWidgetView: View {
@Environment(\.widgetRenderingMode) var renderingMode
var body: some View {
if renderingMode == .accented {
// 着色模式:白色调色,主题化玻璃背景
} else {
// 全彩模式:标准外观
}
}
}
HStack {
VStack(alignment: .leading) {
Text("Title")
.widgetAccentable() // 强调组
Text("Subtitle")
// 主组(默认)
}
Image(systemName: "star.fill")
.widgetAccentable() // 强调组
}
Image("myImage")
.widgetAccentedRenderingMode(.monochrome)
VStack { /* content */ }
.containerBackground(for: .widget) {
Color.blue.opacity(0.2)
}
| 决策 | 理由 |
|---|---|
| 使用 GlassEffectContainer 包装 | 性能优化,支持玻璃元素之间的变形 |
spacing 参数 | 控制合并距离——微调元素需要多近才能融合 |
@Namespace + glassEffectID | 在视图层次结构变化时实现平滑的变形过渡 |
interactive() 修饰符 | 明确选择启用触摸/指针反应——并非所有玻璃都应响应 |
| UIKit 中的 UIGlassContainerEffect | 与 SwiftUI 保持一致的容器模式 |
| 小组件中的着色渲染模式 | 当用户选择着色的主屏幕时,系统应用着色玻璃 |
.glassEffect().interactive()withAnimation 以启用平滑的变形过渡.glassEffect() 视图而没有 GlassEffectContainerclipsToBounds = true每周安装量
380
代码仓库
GitHub 星标数
69.1K
首次出现
14 天前
安全审计
安装于
codex363
gemini-cli341
github-copilot339
opencode339
cursor339
amp338
Patterns for implementing Apple's Liquid Glass — a dynamic material that blurs content behind it, reflects color and light from surrounding content, and reacts to touch and pointer interactions. Covers SwiftUI, UIKit, and WidgetKit integration.
The simplest way to add Liquid Glass to any view:
Text("Hello, World!")
.font(.title)
.padding()
.glassEffect() // Default: regular variant, capsule shape
Text("Hello, World!")
.font(.title)
.padding()
.glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0))
Key customization options:
.regular — standard glass effect.tint(Color) — add color tint for prominence.interactive() — react to touch and pointer interactions.capsule (default), .rect(cornerRadius:), .circleButton("Click Me") { /* action */ }
.buttonStyle(.glass)
Button("Important") { /* action */ }
.buttonStyle(.glassProminent)
Always wrap multiple glass views in a container for performance and morphing:
GlassEffectContainer(spacing: 40.0) {
HStack(spacing: 40.0) {
Image(systemName: "scribble.variable")
.frame(width: 80.0, height: 80.0)
.font(.system(size: 36))
.glassEffect()
Image(systemName: "eraser.fill")
.frame(width: 80.0, height: 80.0)
.font(.system(size: 36))
.glassEffect()
}
}
The spacing parameter controls merge distance — closer elements blend their glass shapes together.
Combine multiple views into a single glass shape with glassEffectUnion:
@Namespace private var namespace
GlassEffectContainer(spacing: 20.0) {
HStack(spacing: 20.0) {
ForEach(symbolSet.indices, id: \.self) { item in
Image(systemName: symbolSet[item])
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectUnion(id: item < 2 ? "group1" : "group2", namespace: namespace)
}
}
}
Create smooth morphing when glass elements appear/disappear:
@State private var isExpanded = false
@Namespace private var namespace
GlassEffectContainer(spacing: 40.0) {
HStack(spacing: 40.0) {
Image(systemName: "scribble.variable")
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectID("pencil", in: namespace)
if isExpanded {
Image(systemName: "eraser.fill")
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectID("eraser", in: namespace)
}
}
}
Button("Toggle") {
withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)
To allow horizontal scroll content to extend under a sidebar or inspector, ensure the ScrollView content reaches the leading/trailing edges of the container. The system automatically handles the under-sidebar scrolling behavior when the layout extends to the edges — no additional modifier is needed.
let glassEffect = UIGlassEffect()
glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3)
glassEffect.isInteractive = true
let visualEffectView = UIVisualEffectView(effect: glassEffect)
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.layer.cornerRadius = 20
visualEffectView.clipsToBounds = true
view.addSubview(visualEffectView)
NSLayoutConstraint.activate([
visualEffectView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
visualEffectView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
visualEffectView.widthAnchor.constraint(equalToConstant: 200),
visualEffectView.heightAnchor.constraint(equalToConstant: 120)
])
// Add content to contentView
let label = UILabel()
label.text = "Liquid Glass"
label.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.contentView.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: visualEffectView.contentView.centerXAnchor),
label.centerYAnchor.constraint(equalTo: visualEffectView.contentView.centerYAnchor)
])
let containerEffect = UIGlassContainerEffect()
containerEffect.spacing = 40.0
let containerView = UIVisualEffectView(effect: containerEffect)
let firstGlass = UIVisualEffectView(effect: UIGlassEffect())
let secondGlass = UIVisualEffectView(effect: UIGlassEffect())
containerView.contentView.addSubview(firstGlass)
containerView.contentView.addSubview(secondGlass)
scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true
let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
favoriteButton.hidesSharedBackground = true // Opt out of shared glass background
struct MyWidgetView: View {
@Environment(\.widgetRenderingMode) var renderingMode
var body: some View {
if renderingMode == .accented {
// Tinted mode: white-tinted, themed glass background
} else {
// Full color mode: standard appearance
}
}
}
HStack {
VStack(alignment: .leading) {
Text("Title")
.widgetAccentable() // Accent group
Text("Subtitle")
// Primary group (default)
}
Image(systemName: "star.fill")
.widgetAccentable() // Accent group
}
Image("myImage")
.widgetAccentedRenderingMode(.monochrome)
VStack { /* content */ }
.containerBackground(for: .widget) {
Color.blue.opacity(0.2)
}
| Decision | Rationale |
|---|---|
| GlassEffectContainer wrapping | Performance optimization, enables morphing between glass elements |
spacing parameter | Controls merge distance — fine-tune how close elements must be to blend |
@Namespace + glassEffectID | Enables smooth morphing transitions on view hierarchy changes |
interactive() modifier | Explicit opt-in for touch/pointer reactions — not all glass should respond |
| UIGlassContainerEffect in UIKit | Same container pattern as SwiftUI for consistency |
| Accented rendering mode in widgets | System applies tinted glass when user selects tinted Home Screen |
.glassEffect() after other appearance modifiers (frame, font, padding).interactive() only on elements that respond to user interaction (buttons, toggleable items)withAnimation when changing view hierarchies to enable smooth morphing transitions.glassEffect() views without a GlassEffectContainerclipsToBounds = true in UIKit when using corner radiiWeekly Installs
380
Repository
GitHub Stars
69.1K
First Seen
14 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex363
gemini-cli341
github-copilot339
opencode339
cursor339
amp338
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
103,800 周安装