liquid-glass について
Liquid Glass は、iOS 26 以降の Liquid Glass マテリアルを使う SwiftUI の画面をレビュー・改善・実装するスキルです。修飾子の順序、要素のグループ化、操作、遷移、旧バージョン向けの代替表示を案内します。
主な機能
- 01既存のガラス UI のレビュー指針
- 02新機能と改修の実装パターン
- 03修飾子の順序とコンテナのルール
- 04インタラクションとモーフィング遷移
- 05iOS 26 以降の可用性確認と代替表示
活用シーン
- 01SwiftUI 画面での Liquid Glass の使い方を確認
- 02ボタンやカードへのガラス表現の追加
- 03旧 iOS バージョン向け代替 UI の用意
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ patrickserrano/ skills --skill liquid-glassインストール後、Claude Code で/liquid-glassを入力して読み込まれたか確認します。
詳細
SwiftUI Liquid Glass
概要
Liquid Glass は iOS 26 以降で利用できる動的なマテリアルで、光学ガラスの特性と流動性を組み合わせています。コンテンツをぼかし、周囲の色や光を反射し、タッチ操作にリアルタイムで反応します。
ワークフローの判断ツリー
1) 既存の機能をレビューする
- Liquid Glass を使用すべき箇所と使用すべきでない箇所を確認します
- モディファイアの順序、シェイプの使い方、コンテナの配置が適切か確認します
- iOS 26 以降への対応処理とフォールバックを確認します
2) Liquid Glass を使用して機能を改善する
- 対象のコンポーネント(サーフェス、チップ、ボタン、カード)を特定します
- 複数のガラス要素には
GlassEffectContainerを使うようリファクタリングします - タップやフォーカスに対応する要素にのみ、インタラクティブなガラス効果を追加します
3) Liquid Glass を使用して新機能を実装する
- まずガラスのサーフェスとインタラクションを設計します(シェイプ、強調度、グループ化)
- レイアウトや外観のモディファイアの後にガラスのモディファイアを追加します
- アニメーションに伴ってビュー階層が変化する場合にのみ、モーフィングトランジションを追加します
基本ガイドライン
- カスタムのぼかしより、ネイティブの Liquid Glass API を優先します
- 複数のガラス要素が共存する場合は
GlassEffectContainerを使用します .glassEffect(...)はレイアウトや視覚効果のモディファイアの後に適用します- タッチやポインターに反応する要素には
.interactive()を使用します - 関連する要素間でシェイプを統一します
#available(iOS 26, *)で対応状況を確認し、ガラス効果を使わないフォールバックを用意します
レビューチェックリスト
- 対応状況:フォールバック UI とともに
#available(iOS 26, *)がある - 合成:複数のガラスビューが
GlassEffectContainerで囲まれている - モディファイアの順序:レイアウトや外観のモディファイアの後に
glassEffectが適用されている - インタラクティブ性:
interactive()がユーザー操作のある箇所にのみ使われている - トランジション:モーフィングに
@NamespaceとともにglassEffectIDが使われている - 一貫性:機能全体でシェイプ、色合い、間隔が統一されている
実装チェックリスト
- 対象要素と、求めるガラス効果の強調度を定義する
- グループ化したガラス要素を、間隔を指定して
GlassEffectContainerで囲む - 必要に応じて
.glassEffect(.regular.tint(...).interactive(), in: .rect(cornerRadius: ...))を使う - アクションには
.buttonStyle(.glass)/.buttonStyle(.glassProminent)を使う - ビュー階層が変化する場合は、
glassEffectIDでモーフィングトランジションを追加する - 以前の iOS バージョン向けにフォールバックマテリアルを用意する
クイックスニペット
フォールバック付きの基本的なガラス効果
if #available(iOS 26, *) {
Text("Hello")
.padding()
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 16))
} else {
Text("Hello")
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
}
複数のガラス要素
GlassEffectContainer(spacing: 24) {
HStack(spacing: 24) {
Image(systemName: "scribble.variable")
.frame(width: 72, height: 72)
.font(.system(size: 32))
.glassEffect()
Image(systemName: "eraser.fill")
.frame(width: 72, height: 72)
.font(.system(size: 32))
.glassEffect()
}
}
ガラスボタン
Button("Confirm") { }
.buttonStyle(.glassProminent)
Button("Cancel") { }
.buttonStyle(.glass)
モーフィングトランジション
@State private var isExpanded = false
@Namespace private var namespace
GlassEffectContainer(spacing: 40) {
HStack(spacing: 40) {
Image(systemName: "pencil")
.frame(width: 80, height: 80)
.glassEffect()
.glassEffectID("pencil", in: namespace)
if isExpanded {
Image(systemName: "eraser")
.frame(width: 80, height: 80)
.glassEffect()
.glassEffectID("eraser", in: namespace)
}
}
}
Button("Toggle") {
withAnimation {
isExpanded.toggle()
}
}
.buttonStyle(.glass)
ガラス効果のカスタマイズ
Text("Tinted Glass")
.padding()
.glassEffect(.regular.tint(.orange).interactive(), in: .capsule)
ガラス効果の結合
@Namespace private var namespace
GlassEffectContainer(spacing: 20) {
HStack(spacing: 20) {
ForEach(items.indices, id: \.self) { index in
ItemView(item: items[index])
.glassEffect()
.glassEffectUnion(id: index < 2 ? "group1" : "group2", namespace: namespace)
}
}
}
シェイプのオプション
.capsule(デフォルト).rect(cornerRadius: CGFloat).circle
ベストプラクティス
- コンテナの使用:複数のガラスビューには必ず
GlassEffectContainerを使用します - モディファイアの順序:外観のモディファイアの後に
.glassEffect()を適用します - 間隔:効果の結合を調整できるよう、間隔の値を慎重に選びます
- アニメーション:スムーズなモーフィングのため、ビュー階層を変更するときはアニメーションを使用します
- インタラクティブ性:タッチ可能な要素にのみ
.interactive()を追加します - 一貫性:アプリ全体でシェイプとスタイルを統一します
コメント
Markdown 対応