swiftui-liquid-glass について
swiftui-liquid-glassは、SwiftUIでネイティブなLiquid Glass UIをレビュー、実装するためのスキルです。iOS 26以降のAPI選択、レイアウト、利用可能性チェック、視覚上の注意点を扱います。
主な機能
- 01ネイティブなガラスボタンスタイルの選択
- 02カスタムビューへのガラス効果の適用
- 03隣接するガラス要素のグループ化
- 04safeAreaBarによるボトムバーの配置
- 05ツールバーとシンボルの規則の確認
- 06旧バージョンのiOS向けフォールバック
活用シーン
- 01独自のぼかしによるガラス表現のリファクタリング
- 02ガラスボタンとカスタムサーフェスの実装
- 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 を使用します。マテリアル、ぼかし、シャドウを使って効果を再現しないでください。
基本ルール
- カスタム Liquid Glass を作成しないでください。背景、アウトライン、ぼかし、シャドウを追加して作成することは禁止です。
- ボタン — スタイル:色のないボタンには
.buttonStyle(.glass)、色付きのボタンには.buttonStyle(.glassProminent)を使用します。.glassProminentは.tint()に対応していますが、指定できるのは色のみで、グラデーションは指定できません。 - ボタン — 形状:ボタンのラベルに手動で形状を適用するのではなく、
.buttonBorderShape()を使用します。 - ボタン — パディング:このボタン設定を使用すると、Liquid Glass の形状の内側に約 13pt のパディングが追加されます。デザインを調整する際は、この点を考慮してください。
- カスタムビュー:
.glassEffect(.regular, in: ...)を使用して、カスタム View を Liquid Glass コンテナー内に配置します。 - グループ化された Glass:複数の Liquid Glass 要素が隣り合う場合は、
GlassEffectContainerを使用します。この View/Container は、要素が拡大して互いに触れると、Liquid Merge 効果を追加します。 - スクロール:ScrollView や List(スクロールするもの)内では、Liquid Glass の使用を避けてください。
- 下部バー:Liquid Glass の View を画面下部に固定する場合は、VStack や
.overlay()ではなく、.safeAreaBar(.bottom)内に配置してください。safeAreaBar はコンテンツの背後に控えめなぼかし効果を追加します。 - ツールバー項目 — Glass を表示しない場合:iOS 26 以降では、ナビゲーションバーとウィンドウのツールバー項目に、デフォルトで共通の Liquid Glass 背景が適用されます。Glass のカプセルを表示しない項目(シンプルなアイコン、カスタムラベル、ステータステキスト、ロゴ)には、内側の View ではなく
ToolbarItemに.sharedBackgroundVisibility(.hidden)を適用してください。 - 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) 実装またはリファクタリングする
- 適切なプリミティブ(ボタンスタイル、
glassEffect、safeAreaBar)を選びます。 - まずレイアウトとタイポグラフィを適用し、最後に Glass モディファイアを追加します。
- 隣り合う Glass 要素を
GlassEffectContainerで囲みます。 - デザインを合わせる際は、ボタン内部に約 13pt のパディングがあることを考慮します。
- Glass の形状で囲みの形状を定義できるよう、囲みなし SF Symbols を使用します。
- 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, *)を使用している
追加リソース
- API の詳細と変形トランジション:reference.md
- カスタムビューへの Liquid Glass の適用
- Landmarks:Liquid Glass を使ったアプリの構築