mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-14 22:13:41 +08:00
* docs(zh-CN): sync Chinese docs with latest upstream changes * update --------- Co-authored-by: neo <neo.dowithless@gmail.com>
281 lines
8.6 KiB
Markdown
281 lines
8.6 KiB
Markdown
---
|
||
name: liquid-glass-design
|
||
description: iOS 26 液态玻璃设计系统 — 适用于 SwiftUI、UIKit 和 WidgetKit 的动态玻璃材质,具有模糊、反射和交互式变形效果。
|
||
---
|
||
|
||
# Liquid Glass 设计系统 (iOS 26)
|
||
|
||
实现苹果 Liquid Glass 的模式指南——这是一种动态材质,会模糊其后的内容,反射周围内容的颜色和光线,并对触摸和指针交互做出反应。涵盖 SwiftUI、UIKit 和 WidgetKit 集成。
|
||
|
||
## 何时启用
|
||
|
||
* 为 iOS 26+ 构建或更新采用新设计语言的应用程序时
|
||
* 实现玻璃风格的按钮、卡片、工具栏或容器时
|
||
* 在玻璃元素之间创建变形过渡时
|
||
* 将 Liquid Glass 效果应用于小组件时
|
||
* 将现有的模糊/材质效果迁移到新的 Liquid Glass API 时
|
||
|
||
## 核心模式 — SwiftUI
|
||
|
||
### 基本玻璃效果
|
||
|
||
为任何视图添加 Liquid Glass 的最简单方法:
|
||
|
||
```swift
|
||
Text("Hello, World!")
|
||
.font(.title)
|
||
.padding()
|
||
.glassEffect() // Default: regular variant, capsule shape
|
||
```
|
||
|
||
### 自定义形状和色调
|
||
|
||
```swift
|
||
Text("Hello, World!")
|
||
.font(.title)
|
||
.padding()
|
||
.glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0))
|
||
```
|
||
|
||
关键自定义选项:
|
||
|
||
* `.regular` — 标准玻璃效果
|
||
* `.tint(Color)` — 添加颜色色调以增强突出度
|
||
* `.interactive()` — 对触摸和指针交互做出反应
|
||
* 形状:`.capsule`(默认)、`.rect(cornerRadius:)`、`.circle`
|
||
|
||
### 玻璃按钮样式
|
||
|
||
```swift
|
||
Button("Click Me") { /* action */ }
|
||
.buttonStyle(.glass)
|
||
|
||
Button("Important") { /* action */ }
|
||
.buttonStyle(.glassProminent)
|
||
```
|
||
|
||
### 用于多个元素的 GlassEffectContainer
|
||
|
||
出于性能和变形考虑,始终将多个玻璃视图包装在一个容器中:
|
||
|
||
```swift
|
||
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` 将多个视图组合成单个玻璃形状:
|
||
|
||
```swift
|
||
@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)
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 变形过渡
|
||
|
||
在玻璃元素出现/消失时创建平滑的变形效果:
|
||
|
||
```swift
|
||
@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` 内容到达容器的 leading/trailing 边缘。当布局延伸到边缘时,系统会自动处理侧边栏下方的滚动行为——无需额外的修饰符。
|
||
|
||
## 核心模式 — UIKit
|
||
|
||
### 基本 UIGlassEffect
|
||
|
||
```swift
|
||
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)
|
||
])
|
||
```
|
||
|
||
### 用于多个元素的 UIGlassContainerEffect
|
||
|
||
```swift
|
||
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)
|
||
```
|
||
|
||
### 滚动边缘效果
|
||
|
||
```swift
|
||
scrollView.topEdgeEffect.style = .automatic
|
||
scrollView.bottomEdgeEffect.style = .hard
|
||
scrollView.leftEdgeEffect.isHidden = true
|
||
```
|
||
|
||
### 工具栏玻璃集成
|
||
|
||
```swift
|
||
let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
|
||
favoriteButton.hidesSharedBackground = true // Opt out of shared glass background
|
||
```
|
||
|
||
## 核心模式 — WidgetKit
|
||
|
||
### 渲染模式检测
|
||
|
||
```swift
|
||
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
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 用于视觉层次结构的强调色组
|
||
|
||
```swift
|
||
HStack {
|
||
VStack(alignment: .leading) {
|
||
Text("Title")
|
||
.widgetAccentable() // Accent group
|
||
Text("Subtitle")
|
||
// Primary group (default)
|
||
}
|
||
Image(systemName: "star.fill")
|
||
.widgetAccentable() // Accent group
|
||
}
|
||
```
|
||
|
||
### 强调模式下的图像渲染
|
||
|
||
```swift
|
||
Image("myImage")
|
||
.widgetAccentedRenderingMode(.monochrome)
|
||
```
|
||
|
||
### 容器背景
|
||
|
||
```swift
|
||
VStack { /* content */ }
|
||
.containerBackground(for: .widget) {
|
||
Color.blue.opacity(0.2)
|
||
}
|
||
```
|
||
|
||
## 关键设计决策
|
||
|
||
| 决策 | 理由 |
|
||
|----------|-----------|
|
||
| 使用 GlassEffectContainer 包装 | 性能优化,实现玻璃元素之间的变形 |
|
||
| `spacing` 参数 | 控制合并距离——微调元素需要多近才能融合 |
|
||
| `@Namespace` + `glassEffectID` | 在视图层次结构变化时实现平滑的变形过渡 |
|
||
| `interactive()` 修饰符 | 明确选择加入触摸/指针反应——并非所有玻璃都应响应 |
|
||
| UIKit 中的 UIGlassContainerEffect | 与 SwiftUI 保持一致的容器模式 |
|
||
| 小组件中的强调色渲染模式 | 当用户选择带色调的主屏幕时,系统会应用带色调的玻璃效果 |
|
||
|
||
## 最佳实践
|
||
|
||
* **始终使用 GlassEffectContainer** 来为多个兄弟视图应用玻璃效果——它支持变形并提高渲染性能
|
||
* **在其他外观修饰符**(frame、font、padding)**之后应用** `.glassEffect()`
|
||
* **仅在响应用户交互的元素**(按钮、可切换项目)**上使用** `.interactive()`
|
||
* **仔细选择容器中的间距**,以控制玻璃效果何时合并
|
||
* 在更改视图层次结构时**使用** `withAnimation`,以启用平滑的变形过渡
|
||
* **在各种外观模式下测试**——浅色模式、深色模式和强调色/色调模式
|
||
* **确保可访问性对比度**——玻璃上的文本必须保持可读性
|
||
|
||
## 应避免的反模式
|
||
|
||
* 使用多个独立的 `.glassEffect()` 视图而不使用 GlassEffectContainer
|
||
* 嵌套过多玻璃效果——会降低性能和视觉清晰度
|
||
* 对每个视图都应用玻璃效果——保留给交互元素、工具栏和卡片
|
||
* 在 UIKit 中使用圆角时忘记 `clipsToBounds = true`
|
||
* 忽略小组件中的强调色渲染模式——破坏带色调的主屏幕外观
|
||
* 在玻璃效果后面使用不透明背景——破坏了半透明效果
|
||
|
||
## 使用场景
|
||
|
||
* 采用 iOS 26 新设计的导航栏、工具栏和标签栏
|
||
* 浮动操作按钮和卡片式容器
|
||
* 需要视觉深度和触摸反馈的交互控件
|
||
* 应与系统 Liquid Glass 外观集成的小组件
|
||
* 相关 UI 状态之间的变形过渡
|