選項
首頁首頁 Skill 其他 liquid-glass-design

liquid-glass-design

affaan-m/ECC affaan-m/ECC

在 SwiftUI、UIKit 和 WidgetKit 中實作 Apple 的 Liquid Glass 設計系統(適用於 iOS 26 及以上版本),包含動態玻璃材質、模糊效果、反射效果以及互動式變形效果。

...展開全部
7
更新時間 2026-10-12

液態玻璃設計系統 (iOS 26)

本指南提供實現 Apple「液態玻璃」效果的實作範例——這是一種動態材質,能模糊背後內容、反射周邊內容的色彩與光線,並對觸控及游標互動做出反應。內容涵蓋 SwiftUI、UIKit 及 WidgetKit 的整合應用。

何時啟用

  • 使用新設計語言開發或更新適用於 iOS 26 及以上版本的應用程式
  • 實作玻璃風格的按鈕、卡片、工具列或容器
  • 在玻璃元素之間建立變形轉場效果
  • 將 Liquid Glass 效果套用至小工具
  • 將現有的模糊/Material 效果遷移至新的 Liquid Glass API

核心模式 — SwiftUI

基本玻璃效果

為任何視圖新增「液態玻璃」效果的最簡單方法:

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)— 添加色彩濾鏡以增強視覺效果
  • .interactive()— 對觸控與游標互動做出反應
  • 形狀:.capsule(預設)、.rect(cornerRadius:)、.circle

玻璃按鈕樣式

Button("點擊我") { /* 動作 */ }
    .buttonStyle(.glass)

Button("重要") { /* 動作 */ }
    .buttonStyle(.glassProminent)

適用於多個元素的 GlassEffectContainer

為確保效能與變形效果,請務必將多個玻璃視圖包裹在容器中:

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()
    }
}

間距參數用來控制融合距離——距離越近的元素,其玻璃形狀的融合效果就越明顯。

合併玻璃效果

使用 `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("切換") {
    withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)

將橫向捲動延伸至側邊欄下方

若要讓水平捲動內容延伸至側邊欄或檢視器下方,請確保ScrollView的內容能觸及容器的左側/右側邊緣。當佈局延伸至邊緣時,系統會自動處理側邊欄下方的捲動行為——無需額外的修飾子。

核心模式 — UIKit

基本 UIGlassEffect

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)
])

適用於多個元素的 UIGlassContainerEffect

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  // 停用共用玻璃背景

核心模式 — WidgetKit

渲染模式偵測

struct MyWidgetView: View {
    @Environment(\.widgetRenderingMode) var renderingMode

    var body: some View {
        if renderingMode == .accented {
            // 著色模式:白色著色、主題化玻璃背景
        } else {
            // 全彩模式:標準外觀
        }
    }
}

用於視覺層級的強調群組

HStack {
    VStack(alignment: .leading) {
        Text("標題")
            .widgetAccentable()  // 強調組
        Text("副標題")
            // 主要組(預設)
    }
    Image(systemName: "star.fill")
        .widgetAccentable()  // 強調群組
}

重點模式下的圖片渲染

Image("myImage")
    .widgetAccentedRenderingMode(.monochrome)

容器背景

VStack { /* 內容 */ }
    .containerBackground(for: .widget) {
        Color.blue.opacity(0.2)
    }

關鍵設計決策

決策 理由
GlassEffectContainer 包裹 效能優化,可實現玻璃元件之間的變形效果
間距參數 控制合併距離 — 微調元素必須多接近才能融合
@Namespace+glassEffectID 在檢視層級變更時啟用平滑的變形過渡
interactive()修飾子 明確啟用觸控/游標反應 — 並非所有玻璃元素都應做出反應
UIKit 中的 UIGlassContainerEffect 為保持一致性,採用與 SwiftUI 相同的容器模式
小部件中的帶色渲染模式 當使用者選擇帶色調的主畫面時,系統會套用帶色調的玻璃效果

最佳實務

  • 當需為多個同級視圖套用玻璃效果時,請務必使用 GlassEffectContainer— 它能啟用變形效果並提升渲染效能
  • 請在其他外觀修飾子(框架、字型、內距)之後才套用.glassEffect()
  • 僅對會響應使用者互動的元素(按鈕、可切換項目)使用.interactive()
  • 請謹慎設定容器內的間距,以控制玻璃效果何時融合
  • 變更視圖層級時,請搭配使用withAnimation以實現平滑的變形過渡
  • 請在各種外觀模式下進行測試— 淺色模式、深色模式,以及強調色/色調模式
  • 確保無障礙對比度— 玻璃上的文字必須保持可讀性

應避免的反模式

  • 未使用 GlassEffectContainer 而直接使用多個獨立的.glassEffect()視圖
  • 過度嵌套玻璃效果 — 會降低效能並影響視覺清晰度
  • 將玻璃效果套用至每個視圖 — 應保留給互動式元素、工具列及卡片
  • 在使用圓角時,忘記在 UIKit 中設定clipsToBounds = true
  • 忽略小工具中的「帶重音符號」渲染模式 — 會破壞主畫面帶色調的外觀
  • 在玻璃效果後方使用不透明背景 — 會抵消半透明效果

何時使用

  • 採用全新 iOS 26 設計的導覽列、工具列及分頁列
  • 懸浮動作按鈕與卡片式容器
  • 需要視覺深度與觸控回饋的互動式控制項
  • 應與系統「液態玻璃」外觀整合的小工具
  • 相關 UI 狀態之間的變形轉場效果
在 GitHub 上查看
---
name: liquid-glass-design
description: Implement Apple's Liquid Glass design system for iOS 26+ with dynamic glass materials, blur, reflection, and interactive morphing in SwiftUI, UIKit, and WidgetKit.
---

# Liquid Glass Design System (iOS 26)

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.

## When to Activate

- Building or updating apps for iOS 26+ with the new design language
- Implementing glass-style buttons, cards, toolbars, or containers
- Creating morphing transitions between glass elements
- Applying Liquid Glass effects to widgets
- Migrating existing blur/material effects to the new Liquid Glass API

## Core Pattern — SwiftUI

### Basic Glass Effect

The simplest way to add Liquid Glass to any view:

```swift
Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect()  // Default: regular variant, capsule shape
```

### Customizing Shape and Tint

```swift
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
- Shape: `.capsule` (default), `.rect(cornerRadius:)`, `.circle`

### Glass Button Styles

```swift
Button("Click Me") { /* action */ }
    .buttonStyle(.glass)

Button("Important") { /* action */ }
    .buttonStyle(.glassProminent)
```

### GlassEffectContainer for Multiple Elements

Always wrap multiple glass views in a container for performance and morphing:

```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()
    }
}
```

The `spacing` parameter controls merge distance — closer elements blend their glass shapes together.

### Uniting Glass Effects

Combine multiple views into a single glass shape with `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)
        }
    }
}
```

### Morphing Transitions

Create smooth morphing when glass elements appear/disappear:

```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)
```

### Extending Horizontal Scrolling Under Sidebar

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.

## Core Pattern — UIKit

### Basic 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 for Multiple Elements

```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)
```

### Scroll Edge Effects

```swift
scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true
```

### Toolbar Glass Integration

```swift
let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
favoriteButton.hidesSharedBackground = true  // Opt out of shared glass background
```

## Core Pattern — WidgetKit

### Rendering Mode Detection

```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
        }
    }
}
```

### Accent Groups for Visual Hierarchy

```swift
HStack {
    VStack(alignment: .leading) {
        Text("Title")
            .widgetAccentable()  // Accent group
        Text("Subtitle")
            // Primary group (default)
    }
    Image(systemName: "star.fill")
        .widgetAccentable()  // Accent group
}
```

### Image Rendering in Accented Mode

```swift
Image("myImage")
    .widgetAccentedRenderingMode(.monochrome)
```

### Container Background

```swift
VStack { /* content */ }
    .containerBackground(for: .widget) {
        Color.blue.opacity(0.2)
    }
```

## Key Design Decisions

| 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 |

## Best Practices

- **Always use GlassEffectContainer** when applying glass to multiple sibling views — it enables morphing and improves rendering performance
- **Apply `.glassEffect()` after** other appearance modifiers (frame, font, padding)
- **Use `.interactive()`** only on elements that respond to user interaction (buttons, toggleable items)
- **Choose spacing carefully** in containers to control when glass effects merge
- **Use `withAnimation`** when changing view hierarchies to enable smooth morphing transitions
- **Test across appearances** — light mode, dark mode, and accented/tinted modes
- **Ensure accessibility contrast** — text on glass must remain readable

## Anti-Patterns to Avoid

- Using multiple standalone `.glassEffect()` views without a GlassEffectContainer
- Nesting too many glass effects — degrades performance and visual clarity
- Applying glass to every view — reserve for interactive elements, toolbars, and cards
- Forgetting `clipsToBounds = true` in UIKit when using corner radii
- Ignoring accented rendering mode in widgets — breaks tinted Home Screen appearance
- Using opaque backgrounds behind glass — defeats the translucency effect

## When to Use

- Navigation bars, toolbars, and tab bars with the new iOS 26 design
- Floating action buttons and card-style containers
- Interactive controls that need visual depth and touch feedback
- Widgets that should integrate with the system's Liquid Glass appearance
- Morphing transitions between related UI states

所有檔案

1 個檔案

安裝 liquid-glass-design

請下載並將技能檔案解壓縮至您的 .claude/skills/ 目錄中。

下載 ZIP

複製儲存庫並將技能檔案複製到您的專案中。

git clone https://github.com/affaan-m/ECC/tree/main/skills/liquid-glass-design # Copy SKILL.md to your .claude/skills/ directory

複製 複製
快速設定: 將技能資料夾複製到 .claude/skills/ Claude 會自動偵測並使用該技能
儲存庫 affaan-m/ECC

相關技能

v4-new-features
更新時間 2026-08-04
multica-creating-agents
更新時間 2026-08-12
pixijs-application
更新時間 2026-08-04
tilemaps
更新時間 2026-08-04
OR