liquid-glass-design

liquid-glass-design

熱門

iOS 26 Liquid Glass 設計系統 — 動態玻璃材質,支援模糊、反射與互動變形,適用於 SwiftUI、UIKit 和 WidgetKit。

23萬星標
3.5萬分支
更新於 2026/7/14
SKILL.md
readonlyread-only
name
liquid-glass-design
description

iOS 26 Liquid Glass 設計系統 — 動態玻璃材質,支援模糊、反射與互動變形,適用於 SwiftUI、UIKit 和 WidgetKit。

Liquid Glass 設計系統 (iOS 26)

實作 Apple Liquid Glass 的模式 — 一種動態材質,能模糊後方內容、反射周圍內容的顏色與光線,並回應觸控與指標互動。涵蓋 SwiftUI、UIKit 與 WidgetKit 整合。

啟用時機

  • 為 iOS 26+ 建置或更新 App,採用新的設計語言
  • 實作玻璃風格的按鈕、卡片、工具列或容器
  • 在玻璃元素之間建立變形轉場
  • 將 Liquid Glass 效果套用到 Widget
  • 將現有的模糊/材質效果遷移至新的 Liquid Glass API

核心模式 — SwiftUI

基本玻璃效果

為任何視圖加入 Liquid Glass 最簡單的方式:

Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect()  // 預設:regular 變體,膠囊形狀

自訂形狀與色調

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("Click Me") { /* 動作 */ }
    .buttonStyle(.glass)

Button("Important") { /* 動作 */ }
    .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()
    }
}

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 的內容觸及容器的前緣/尾緣。當佈局延伸至邊緣時,系統會自動處理側邊欄下方的捲動行為 — 無需額外修飾詞。

核心模式 — 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("Title")
            .widgetAccentable()  // 強調群組
        Text("Subtitle")
            // 主要群組(預設)
    }
    Image(systemName: "star.fill")
        .widgetAccentable()  // 強調群組
}

強調模式下的圖片渲染

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

容器背景

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

關鍵設計決策

決策 理由
GlassEffectContainer 包裹 效能最佳化,啟用玻璃元素間的變形
spacing 參數 控制合併距離 — 微調元素需多近才能融合
@Namespace + glassEffectID 在視圖層級變更時啟用平滑變形轉場
interactive() 修飾詞 明確選擇加入觸控/指標反應 — 並非所有玻璃都需回應
UIKit 中的 UIGlassContainerEffect 與 SwiftUI 相同的容器模式,保持一致性
Widget 中的強調渲染模式 當使用者選擇色調主畫面時,系統套用有色玻璃

最佳做法

  • 務必使用 GlassEffectContainer 將玻璃效果套用於多個同層視圖 — 可啟用變形並改善渲染效能
  • 在其他外觀修飾詞(frame、font、padding)之後 套用 .glassEffect()
  • 僅在會回應使用者互動的元素(按鈕、可切換項目)上使用 .interactive()
  • 在容器中謹慎選擇 spacing,以控制玻璃效果何時合併
  • 在變更視圖層級時使用 withAnimation,以啟用平滑變形轉場
  • 在不同外觀模式下測試 — 淺色模式、深色模式與強調/色調模式
  • 確保無障礙對比 — 玻璃上的文字必須保持可讀性

應避免的反模式

  • 在沒有 GlassEffectContainer 的情況下使用多個獨立的 .glassEffect() 視圖
  • 嵌套過多玻璃效果 — 會降低效能與視覺清晰度
  • 對每個視圖都套用玻璃效果 — 保留給互動元素、工具列與卡片
  • 在 UIKit 中使用圓角時忘記 clipsToBounds = true
  • 忽略 Widget 中的強調渲染模式 — 會破壞色調主畫面的外觀
  • 在玻璃後方使用不透明背景 — 會破壞半透明效果

使用時機

  • 採用 iOS 26 新設計的導覽列、工具列與標籤列
  • 浮動動作按鈕與卡片式容器
  • 需要視覺深度與觸控回饋的互動控制項
  • 應與系統 Liquid Glass 外觀整合的 Widget
  • 相關 UI 狀態之間的變形轉場