mcpField
S
swiftui-liquid-glass

swiftui-liquid-glass

github.com/flowritescodeデザイン・UI447318 回インストール3 週間前に更新
リポジトリ

swiftui-liquid-glass について

swiftui-liquid-glassは、SwiftUIでネイティブなLiquid Glass UIをレビュー、実装するためのスキルです。iOS 26以降のAPI選択、レイアウト、利用可能性チェック、視覚上の注意点を扱います。

主な機能

  1. 01ネイティブなガラスボタンスタイルの選択
  2. 02カスタムビューへのガラス効果の適用
  3. 03隣接するガラス要素のグループ化
  4. 04safeAreaBarによるボトムバーの配置
  5. 05ツールバーとシンボルの規則の確認
  6. 06旧バージョンのiOS向けフォールバック

活用シーン

  1. 01独自のぼかしによるガラス表現のリファクタリング
  2. 02ガラスボタンとカスタムサーフェスの実装
  3. 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 を使用します。マテリアル、ぼかし、シャドウを使って効果を再現しないでください。

基本ルール

  1. カスタム Liquid Glass を作成しないでください。背景、アウトライン、ぼかし、シャドウを追加して作成することは禁止です。
  2. ボタン — スタイル:色のないボタンには .buttonStyle(.glass)、色付きのボタンには .buttonStyle(.glassProminent) を使用します。.glassProminent は .tint() に対応していますが、指定できるのは色のみで、グラデーションは指定できません。
  3. ボタン — 形状:ボタンのラベルに手動で形状を適用するのではなく、.buttonBorderShape() を使用します。
  4. ボタン — パディング:このボタン設定を使用すると、Liquid Glass の形状の内側に約 13pt のパディングが追加されます。デザインを調整する際は、この点を考慮してください。
  5. カスタムビュー:.glassEffect(.regular, in: ...) を使用して、カスタム View を Liquid Glass コンテナー内に配置します。
  6. グループ化された Glass:複数の Liquid Glass 要素が隣り合う場合は、GlassEffectContainer を使用します。この View/Container は、要素が拡大して互いに触れると、Liquid Merge 効果を追加します。
  7. スクロール:ScrollView や List(スクロールするもの)内では、Liquid Glass の使用を避けてください。
  8. 下部バー:Liquid Glass の View を画面下部に固定する場合は、VStack や .overlay() ではなく、.safeAreaBar(.bottom) 内に配置してください。safeAreaBar はコンテンツの背後に控えめなぼかし効果を追加します。
  9. ツールバー項目 — Glass を表示しない場合:iOS 26 以降では、ナビゲーションバーとウィンドウのツールバー項目に、デフォルトで共通の Liquid Glass 背景が適用されます。Glass のカプセルを表示しない項目(シンプルなアイコン、カスタムラベル、ステータステキスト、ロゴ)には、内側の View ではなく ToolbarItem に .sharedBackgroundVisibility(.hidden) を適用してください。
  10. SF Symbols — 囲み付きシンボルは使用しない:Liquid Glass のボタンやコンテナー内では、囲み付きの SF Symbol バリエーション(plus.circle、xmark.circle.fill、trash.circle など)を使用しないでください。Glass の形状がすでにコンテナーとして機能するため、囲み付きシンボルを使うと不自然な「二重の囲み」(円の中に円)ができます。基本形の囲みなしシンボル(plus、xmark、trash)を使用し、囲みの形状は .buttonBorderShape() または Glass コンテナーで定義してください。

判断フロー

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 を装っているカスタムのぼかし/マテリアルの組み合わせを指摘します。
  • ボタンに独自作成のカプセルではなく、.glass/.glassProminent が使われていることを確認します。
  • ラベルのクリッピングではなく、.buttonBorderShape() が使われていることを確認します。
  • グループ化された要素が GlassEffectContainer 内に配置されていることを確認します。
  • スクロール可能なコンテナー内の Glass を指摘します。
  • 画面下部に固定するバーに .safeAreaBar(.bottom) が使われていることを確認します。
  • Glass なしで表示するツールバー項目には、ToolbarItem に .sharedBackgroundVisibility(.hidden) が使われていることを確認します。
  • Glass ボタンやサーフェス内の囲み付き SF Symbols(例:circle/square バリエーション)を指摘します。
  • #available(iOS 26, *) で利用可能かを判定し、フォールバックを用意します。
2) 実装またはリファクタリングする
  1. 適切なプリミティブ(ボタンスタイル、glassEffect、safeAreaBar)を選びます。
  2. まずレイアウトとタイポグラフィを適用し、最後に Glass モディファイアを追加します。
  3. 隣り合う Glass 要素を GlassEffectContainer で囲みます。
  4. デザインを合わせる際は、ボタン内部に約 13pt のパディングがあることを考慮します。
  5. Glass の形状で囲みの形状を定義できるよう、囲みなし SF Symbols を使用します。
  6. iOS 26 の利用可能性チェックと、iOS 26 より前のバージョン向けフォールバックを追加します。

パターン

Glass ボタン
// 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)

Glass ボタン内では囲み付き 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)
カスタム Glass サーフェス
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))
グループ化された Glass(マージ効果)
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)
    }
}

要素がどのくらい近づくと Liquid Merge が始まるかを、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)
    }
}

.sharedBackgroundVisibility(.hidden) は、内部の Button やラベルではなく、ToolbarItem に適用してください。この効果を非表示にすると、項目は独立したグループに配置され、ガラス背景のある隣接項目との間隔が変わる場合があります。

内部のビューには、このモディファイアを適用しないでください。

// ❌ 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.circle ではなく plus)を使用していない
  • 古い OS 向けのフォールバックを伴う #available(iOS 26, *) を使用している

追加リソース

コメント