🥛

[SwiftUI] iOS 26のLiquid Glass対応をClaudeに丸投げしたら、すけすけになりすぎた話

に公開

[SwiftUI] iOS 26のLiquid Glass対応をClaudeに丸投げしたら、すけすけになりすぎた話

こんにちは、あるぱかです。

個人で開発しているライブのかけ声をカラオケ風に表示するアプリ 「MixFlow」 について、v1.2〜v1.2.1 で iOS 26 の Liquid Glass 対応を行いました。

App Store

https://apps.apple.com/jp/app/id6748905974

MixFlow の紹介記事はこちら(note)

https://note.com/ritsu2891/n/n5b893a5a478d

Claude Code にお任せでいい感じにしてもらえないかなと思ったのですが、だいたいいい感じにしてもらえたものの、過剰にガラス効果を適用してすけすけになってしまいました...🥲

この記事では、今回の Liquid Glass 対応について、Claude Code のような AI エージェントに任せやすい部分/任せにくい部分を、アップデートの途中経過つきで整理します。

TL;DR(結論)

  • Claude Code は「機械的な置き換え」「互換性(#available)を考えた共通モディファイア化」は強い
  • ただし「どこにガラス効果を掛けるか」「ガラス効果が映えるレイアウト調整」は人間の判断が必要
  • まずはアプリ全体へ一括適用 → 画面を見ながら “適用範囲を絞る/重なりを作る” 方向で調整すると進めやすい

Claude Code に任せやすいこと / 任せにくいこと

  • 任せやすい:Color(.systemGray6) などの背景 → ガラス効果背景への置換、共通モディファイア化、#available でのフォールバック
  • 任せにくい:リスト/カードなどへの適用可否の判断、重なり・奥行きの設計、ナビゲーションやモーダルの余白・密度調整

最終成果(Before / After)

MIX(かけ声)表示画面

スクロール領域の上に、Liquid Glass のガラス効果を適用した BPM・拍表示や再生コントロールの UI を配置して立体感が出ました。

MIX(かけ声)表示画面 Before
Before(v1.1.2)

MIX(かけ声)表示画面 After
After(v1.2.1)

このような Liquid Glass のガラス効果をアプリ全体に適用しました。

まず Claude Code に任せたこと(ここまでは良かった)

まずは以下のように、かなりざっくりした依頼プロンプトを入力しました。

このiOSアプリ全体について、iOS26への対応で修正が必要な箇所があれば修正してください。
また、Liquid Glassに適合したUIにしたいです。

すると、プロジェクト構造を把握しつつ、Web から iOS 26 対応・Liquid Glass 対応に関する技術記事を取得するタスクを並行で走らせ、下記のような修正を行ってくれました。

BPM・拍表示や再生コントロールは背景色として Color(.systemGray6) を使っていたのですが、ここをガラス効果の背景に置き換えてくれました。

(1) View の Extension として「ガラス背景」を共通化

ViewExtension.swift
  extension View {
      // ...

+     /**
+         iOS 26以降の場合にLiquid Glass効果を適用し、それ以外の場合にフォールバック背景を適用
+
+         - Parameters:
+             - cornerRadius: 角丸の半径
+             - isInteractive: インタラクティブなGlass効果にするかどうか
+             - tintColor: Glass効果のティントカラー(オプション)
+             - fallbackColor: iOS 26未満で使用する背景色
+      */
+     @ViewBuilder
+     func glassBackground(
+         cornerRadius: CGFloat = 12,
+         isInteractive: Bool = false,
+         tintColor: Color? = nil,
+         fallbackColor: Color = Color(.systemGray6)
+     ) -> some View {
+         if #available(iOS 26.0, *) {
+             self.modifier(GlassBackgroundModifier(
+                 cornerRadius: cornerRadius,
+                 isInteractive: isInteractive,
+                 tintColor: tintColor
+             ))
+         } else {
+             // tintColorが指定されている場合はそれを使用、なければfallbackColorを使用
+             let backgroundColor = tintColor ?? fallbackColor
+             self.background(backgroundColor)
+                 .cornerRadius(cornerRadius)
+         }
+     }

      // ...
  }

+ /// iOS 26以降でLiquid Glass効果を適用するViewModifier
+ @available(iOS 26.0, *)
+ struct GlassBackgroundModifier: ViewModifier {
+     let cornerRadius: CGFloat
+     let isInteractive: Bool
+     let tintColor: Color?
+
+     func body(content: Content) -> some View {
+         if let tintColor = tintColor {
+             if isInteractive {
+                 content.glassEffect(
+                     .regular.tint(tintColor).interactive(),
+                     in: .rect(cornerRadius: cornerRadius)
+                 )
+             } else {
+                 content.glassEffect(
+                     .regular.tint(tintColor),
+                     in: .rect(cornerRadius: cornerRadius)
+                 )
+             }
+         } else {
+             if isInteractive {
+                 content.glassEffect(
+                     .regular.interactive(),
+                     in: .rect(cornerRadius: cornerRadius)
+                 )
+             } else {
+                 content.glassEffect(
+                     .regular,
+                     in: .rect(cornerRadius: cornerRadius)
+                 )
+             }
+         }
+     }
+ }

(2) 上記を各 UI コンポーネントへ適用

MixPageView.swift(一部)
  // ...

  var bpmAndBeatsView: some View {
      BPMAndBeatPositionView(/*... */)
          // ...
-         .background(Color(.systemGray6))
-         .cornerRadius(12)
+         .glassBackground(cornerRadius: 12, isInteractive: true)
          // ...
  }

#available(iOS 26.0, *) で分岐しているので、iOS 26 以上はガラス効果、iOS 26 未満は従来背景(Color(.systemGray6) など)にフォールバックできます。ViewExtension としてまとめることで、置換も方針変更も一箇所で済むのはかなり良かったです。

ただ、こういう「機械的な置換」は強い一方で、実際この時点の UI を見ると以下のような問題がありました。

うまくいかなかった点(見た目の判断が必要)

問題 1:適用範囲が広すぎて「すけすけ」になる

MIX(かけ声)一覧画面・サポート情報画面のリスト項目にまでガラス効果を適用しており、かなりしつこい印象の UI になりました。

初期変更 MIX(かけ声)一覧画面
MIX(かけ声)一覧画面

初期変更 サポート情報画面
サポート情報画面

これは他の UI 要素とも重ならないので「単に影が付いているだけ」になりがちで、ガラス効果は操作ボタンなどに限定して適用した方が引き締まって見えます。

一覧項目などは除外する、といった「適用範囲の判断」は人間が決める必要があります。

問題 2:ガラス効果が映える「重なり」を自動では作れない

MIX(かけ声)表示画面

初期変更 MIX(かけ声)表示画面
MIX(かけ声)表示画面

下部に配置している BPM・拍表示や再生コントロールにはガラス効果が適用されています。ただ、右上に配置しているナビゲーションのボタンは従来のスタイルのままになってたりします。

また、Liquid Glass はコンテンツへの没入感を高める意図があるのに、MIX(かけ声)のスクロールビューがガラス背景と重ならないレイアウトだと、効果が活きません。既存 UI をどう工夫すればガラス効果が活きるか(重なり・奥行き・余白設計)は人間が考える必要があります。

問題 3:ハーフモーダルは「余白の詰め」が必要になる

ハーフモーダルについて、自動的に背景がガラス効果になっているので Liquid Glass のガラス効果導入という意味では特に何も修正する必要はなかったのですが、角がかなり丸くなった影響で上部の余白が足りない印象を受けます。

初期変更 MIX(かけ声)BPM入力ハーフモーダル
MIX(かけ声)BPM 入力ハーフモーダル

最終的にやった調整(ここは人間の領域)

上記の問題を確認した上で、Claude Code で追加プロンプトを出したり、手動で直したりして対応しました。

対応 1:ガラス効果を掛けない箇所を戻す

リスト項目など、ガラス効果が不要な箇所はもとの通り Color(.systemGray6) を単純に適用するだけにしました。

調整 MIX(かけ声)一覧画面
MIX(かけ声)一覧画面

調整 サポート情報画面
サポート情報画面

対応 2:スクロール領域を重ねて没入感を出す

MIX(かけ声)のスクロール領域を拡大して、ガラス効果背景の BPM・拍表示や再生コントロールに重ねるようにし、コンテンツである MIX(かけ声)への没入感を高めました。

調整 MIX(かけ声)表示画面
MIX(かけ声)表示画面

対応 3:ハーフモーダル上部に余白を足す

iOS 26 ではハーフモーダルの上部に余白を加えて、不自然な感じをなくしました。

調整 MIX(かけ声)BPM入力ハーフモーダル
MIX(かけ声)BPM 入力ハーフモーダル

まとめ(AI に任せてよい線引き)

iOS 26 の Liquid Glass 対応でとりあえず Claude Code に任せると、実装面はかなりいい感じに進むものの、見た目は「すけすけ」に寄りがちでした。

今回の記事で書いたように、どこに Liquid Glass のガラス効果を適用するか、既存 UI をどう調整すれば効果が活きるかは視覚的な判断が必要です。ここは人間が方針を決め、AI には「方針に沿った機械的な置換・実装」を任せるのが良さそうだなと思いました。

Discussion