WEARアプリにおけるLiquid Glass対応への第一歩

WEARアプリにおけるLiquid Glass対応への第一歩

はじめに

こんにちは、WEARフロントエンド部iOSブロックの西山です。普段はWEAR iOSチームのマネジメント兼アプリの開発を担当しています。今年のWWDC25で、新しいソフトウェアデザインのLiquid Glassが発表されました。透明感のあるUIと流動的なアニメーションが特徴的なこの新デザインは、WEARアプリに大きな影響を与えました。鋭意進行中の取り組みとして、本記事では、Liquid Glass対応を計画的に進めるための取り組みを紹介します。

目次

Liquid Glassとは

iOS 26から導入される新しいデザインで、次の特徴があります。

  • ガラスのような質感と透明感
  • 光の反射/屈折のようなリアルな動き
  • 流動性のあるアニメーション

https://www.apple.com/jp/newsroom/2025/06/apple-introduces-a-delightful-and-elegant-new-software-design/ より引用

ナビゲーションバーやタブバーなどの標準コンポーネントにデザインが適用されるので既存アプリの確認が必要になります。

課題

WEARアプリの確認と現在の状況を踏まえ、次のような課題がありました。

  • UIが大きく変わることでデザイン崩れが発生
  • デザイナー、エンジニア、QAのコスト増大が予想される
  • Liquid Glassの学習コスト

UIが大きく変わることでデザイン崩れが発生

タブバーとナビゲーションバーを透過させて確認したところ複数の問題が見つかりました。

タブバー

タブバーの裏側にコンテンツが透過しない

Before After
タブバーの裏側に画面がまわらない旧デザイン タブバーの裏側に画面がまわらない新デザイン

タブバーとコンポーネントが被る

Before After
タブバーとコンポーネントが被る旧デザイン タブバーとコンポーネントが被る新デザイン

ナビゲーションバー

ボタンに枠がつく

Before After
ボタンに枠がつく旧デザイン ボタンに枠がつく新デザイン

ナビゲーションバーの下に配置してあるコンポーネントとの一体感を失う

Before After
ナビゲーションバーの下に配置してあるコンポーネントが浮く旧デザイン ナビゲーションバーの下に配置してあるコンポーネントが浮く新デザイン

その他のコンポーネント

Switchが大きくなったことによるレイアウト崩れ

Before After
Switchが大きくなったことによるレイアウト崩れ旧デザイン Switchが大きくなったことによるレイアウト崩れ新デザイン

アラート(アクションシート)の変化

Before After
アラート(アクションシート)の変化旧デザイン アラート(アクションシート)の変化新デザイン

こちらは一部で、この他にも細かいところの問題は存在しています。

デザイナー、エンジニア、QAのコスト増大が予想される

WEARは、基本的に3つのOSをサポートしています。今は過渡期のためiOS 16もサポート中ですが、近々iOS 17, 18, 26のサポートになります。サポートOSは、メジャーバージョンが登場してから数ヶ月後の更新となるため、1年に1回更新されます。そのため、現時点から約2年間は、iOS 26未満をサポートする必要があり、Liquid Glassに対応すると新旧それぞれのデザインを並行管理していく必要が出てきます。それぞれのデザイン調整、開発、テストを行うことで、担当する各チームのコストが増大すると予想されます。

Liquid Glassの学習コスト

新しい概念のため、まずはLiquid Glassを理解する必要があります。既存のコンポーネントのどこをどのような形にすることでLiquid Glassとしてベストなのか見極める必要もあります。まだ登場して間もないため、ノウハウも少なく手探り状態になることは否めません。さらにデザイナーのリソースもこちらに多くを割ける状態ではありませんでした。

移行戦略

リスクと対応コストを考慮し、次の方針で進めます。

  1. Liquid Glassを無効にするオプションをフルで利用する
  2. レイアウト修正を最優先で行う
  3. レイアウト修正を行いながら原因を把握し、デザインや実装方法を見直す
  4. レイアウト修正完了後、Liquid Glassのベストプラクティスを探る
  5. Liquid Glassの為に構造を大きく変える変更は可能であればiOS 18以前にも適用させる

1に関してですが、Appleは、Liquid Glassを無効にするオプションを用意しており、現時点では次のメジャーバージョンリリースまで(約1年)有効とされています。

開発プロセスの整備

修正後は新旧デザインの確認が必要になるため、効率よく進めるための状態を作る必要があります。

ブランチ戦略

普段WEAR iOSでは、developブランチを除外したGit-flowで開発しています。今回の対応では、Liquid Glass用の開発ブランチを作成することも考えられます。しかし、生存期間は長くなりマージコストの増大が懸念されるため既存と同じように進めます。そのため、旧デザインに影響を与えないように対応していく必要があります。

Xcode 26対応

当たり前ですが、Xcode 26対応は必須です。Xcode 26対応の前に先行して進めることもできますがとても非効率になります。

Xcode 16を使用している場合の例

  1. Xcode 26でビルドが通るブランチを用意
  2. Xcode 26で不具合の修正
  3. Xcode 16用のブランチに切り替え
  4. Xcode 16用のブランチに修正を取り込む
  5. Xcode 16でビルドし確認
  6. 問題があれば2から繰り返し

Liquid Glassを無効にする

Liquid Glassを無効にする設定です。 Info.plistUIDesignRequiresCompatibility を追加することで無効にできます。

UIDesignRequiresCompatibilityの設定

Liquid Glass効果を動的に切り替えられるようにする

こちらを参考に swizzling を使ってRelease版には影響がないよう、デバッグメニューから動的に変えられるようにしています。

zenn.dev

デバッグメニューの設定

Liquid Glass対応で分岐できるようにする

同一ブランチでの開発になるため、タブバーの透過等で分岐が必要になります。不具合の修正では極力Liquid Glass用の分岐は入れたくないですが、どうしても必要になるケースも考えられます。また、Liquid Glass無効化オプションの廃止後も、iOS 18をサポートする期間があることを考慮します。

class LiquidGlass: NSObject {
    @objc static var isEnabled: Bool {
        UserDefaults.standard.isLiquidGlassEnabled
    }
}

WEARには一部Objective-Cが残っているため、Objective-Cからも参照できるようにしています。今はデバッグメニューから切り替えられる値を参照してますが、オプションが無効になってからは次のように変える予定です。

class LiquidGlass: NSObject {
    @objc static var isEnabled: Bool {
        if #available(iOS 26.0, *) {
            true
        } else {
            false
        }
    }
}

対応内容を一部紹介

レイアウト修正の中で、最初に取り掛かったのはタブバー周りの対応です。タブバーの背景を透過させるだけでもLiquid Glassらしさが出ます(個人の感想です)

Before After
タブバー旧デザイン タブバー新デザイン

WEARのタブバーは背景色が指定されており、タブバーの裏に画面が回り込むような実装になっていない画面が多数ありました。

そういった画面の大多数はスクロールできる画面なので、ScrollView系を修正します。

※WEARでは、SwiftUIの導入も徐々に進めてはいますが、まだまだUIKitがメインなのでUIKitの対応になります。

主に次の2つを利用しているところの修正が必要でした。

  • contentInsetAdjustmentBehavior = .never
  • extendedLayoutIncludesOpaqueBars = true

contentInsetAdjustmentBehavior = .never の対応

iOS 11以前は scrollView.contentInset を実装側で調整する必要がありましたが、iOS 11からは自動で調整してくれるようになりました。当時の選択肢としては、 never or automatic の2択が取れましたが、 WEARでは never を採用していました。その背景もあり scrollView.contentInset.topcontentInsetAdjustmentBehavior = .never を指定して調整していました。

contentInsetAdjustmentBehavior = .never の問題点

contentInset.top だけの設定であればまだ良かったのですが、今回の対応で contentInset.bottom も調整する必要があります。 never のままだと、タブバーの高さをセットする必要があり煩雑になるので、次の方法に変更しました。

  • contentInsetAdjustmentBehavior = automatic にする(デフォルト値なので指定なし)
  • オートレイアウトの bottomsuperview に貼る

注意点は、今まで scrollView.contentInset を参照している場所は scrollView.adjustedContentInset を参照するように変える必要があるところです。 adjustedContentInset は自動調整された後の値になっているので automatic にした際は、こちらの参照が適切になる箇所が出てきます。

extendedLayoutIncludesOpaqueBars = true の対応

こちらは、ナビゲーションバーの裏側に画面を通すために使用しており、 edgesForExtendedLayout = .top とセットで使用されています。タブバーを透過させるため bottom も追加します。

extendedLayoutIncludesOpaqueBars = true
edgesForExtendedLayout = [.top, .bottom]

ただこれだと旧デザインで、スクロールした最下部のアイテムがタブバーの裏に隠れてしまいます。

最下部のアイテムがタブバーの裏に隠れている

そのため、次のようにします。

extendedLayoutIncludesOpaqueBars = true
edgesForExtendedLayout = isLiquidGlassEnabled ? [.top, .bottom] : .top

極力分岐はしたくないと上述してましたが、早速使ってしまっています。ただこちらは、Liquid Glassのリリースをする前にタブバーを半透明にする対応をリリースし、事前に分岐を無くしておきたいと考えています。

まとめ

本記事ではWEARアプリにおけるLiquid Glass対応を進めるための取り組みを紹介しました。これからLiquid Glass対応に取り組もうとしている方の参考に少しでもなれば幸いです。まずは不具合を修正し、その後、最適なLiquid Glassの対応を模索していければと思います。

ZOZOでは、一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください。

corp.zozo.com

カテゴリー