iOS 26からのLiquid Glassタブの実装を私もしたい

iOS 26からのLiquid Glassタブの実装を私もしたい

2025.09.25

はじめに

スターバックス デジタルテクノロジー部のリルオッサです。

iOS 26がリリースされて、少しずつLiquid Glassに対応したiOSアプリが増えてきました。

Liquid Glassといえば、ナビゲーション周りでガラリとデザインが変わりましたが、まずはあのタブから実装方法を知りたいと思ったので記事にしてみることにしました。

環境

  • Xcode 26.0.1
  • iOS 26.0

Liquid Glass タブの実装

特別な実装は何も必要ありません。標準のタブを使用している場合、Xcode 26.0以降でビルドしたアプリは全てLiquid Glassのタブになります。

スクリーンショット

sample-1

コード

			
			import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView {
            Tab("Red", systemImage: "r.square.fill") {
                Color.red
                    .ignoresSafeArea()
            }

            Tab("Yellow", systemImage: "y.square.fill") {
                Color.yellow
                    .ignoresSafeArea()
            }

            Tab("Green", systemImage: "g.square.fill") {
                Color.green
                    .ignoresSafeArea()
            }
        }
    }
}

		

Liquid Glass タブにしたくない場合

info.plistにUIDesignRequiresCompatibilityというKeyを追加して、Bool値でYESにすることで、一時的に以前のXcodeでビルドした時と同じ外観で表示されます。

sample-2

スクリーンショット

sample-3

注意点

この方法を使うと以前の外観でタブを表示できますが、Apple公式ドキュメントでは最新のデザインに移行するまでの一時的な措置として位置づけられています。

https://developer.apple.com/documentation/BundleResources/Information-Property-List/UIDesignRequiresCompatibility

WWDC25: Platforms State of the Unionでも、このオプションが次のメジャーリリースで削除される予定ということを明言しています。

We intend this option to be removed in the next major release.

なので、この与えらた準備期間の中で新しいデザインに移行していきたいですね。

スクロールした時にタブを最小化する

こちらはiOS 26から登場したtabBarMinimizeBehavior(_:)を使用することで、タブを特定の条件で最小化して、ユーザーがコンテンツにフォーカスを当てやすくなります。

https://developer.apple.com/documentation/swiftui/view/tabbarminimizebehavior(_:)

デモ

下方向にスクロールした時にタブを最小化するようにしています。

https://youtu.be/KksE4uZ3GgM

コード

			
			struct ContentView: View {
    var body: some View {
        TabView {
            Tab("Red", systemImage: "r.square.fill") {
                ScrollView {
                    ForEach(1..<100) {
                        Text("\($0)")
                            .frame(maxWidth: .infinity)
                            .font(.title)
                    }
                }
                .background(.red)
            }

            Tab("Yellow", systemImage: "y.square.fill") {
                Color.yellow
                    .ignoresSafeArea()
            }

            Tab("Green", systemImage: "g.square.fill") {
                Color.green
                    .ignoresSafeArea()
            }
        }
        .tabBarMinimizeBehavior(.onScrollDown) // タブの最小化の設定
    }
}

		

引数として、TabBarMinimizeBehaviorを渡しています。設定できる値は以下になります。

  • automatic
  • never
  • onScrollDown
  • onScrollUp

https://developer.apple.com/documentation/swiftui/tabbarminimizebehavior

ハマった点

個人的にハマった点ですが、この.tabBarMinimizeBehavior(.onScrollDown)ですが、ある程度のスクロール量を確保できないと機能しないような挙動になっていました。

例えば、スクロール内のコンテンツを減らした場合に下方向にスクロールはできるものの、タブが最小化されませんでした。

			
			struct ContentView: View {
    var body: some View {
        TabView {
            Tab("Red", systemImage: "r.square.fill") {
                ScrollView {
                    ForEach(1..<41) {
                        Text("\($0)")
                            .frame(maxWidth: .infinity)
                            .font(.title)
                    }
                }
                .background(.red)
            }
		    // ... 省略

		

https://www.youtube.com/watch?v=LD5JtSgWBTU

検索タブを追加する

TabRole.searchのタブを追加することで検索タブを追加することができ、この検索タブは他のタブとは分離した形で表示されます。
任意のラベルを指定することもできますが、指定しない場合は虫眼鏡magnifyingglassのアイコンになります。

スクリーンショット

sample-4

コード

			
			struct ContentView: View {
    var body: some View {
        TabView {
            Tab("Red", systemImage: "r.square.fill") {
                ScrollView {
                    ForEach(1..<41) {
                        Text("\($0)")
                            .frame(maxWidth: .infinity)
                            .font(.title)
                    }
                }
                .background(.red)
            }

            // ... 省略

		    // 検索タブ
            Tab(role: .search) {
                Color.white
            }
        }
        .tabBarMinimizeBehavior(.onScrollDown)
    }
}

		

検索バーを画面下部に表示させる

Tab(role: .search)で表示するNavigationStack下のViewでsearchableを使用する場合、そのタブがタップされると検索バーが画面下部に表示されます。

デモ

https://www.youtube.com/watch?v=Z68zjF1r9B4

コード

			
			struct ContentView: View {
    @State var searchText = ""

    var body: some View {
        TabView {
            // ... 省略

            Tab(role: .search) {
                NavigationStack {
                    Color.white
                        .searchable(text: $searchText)
                }
            }
			// ... 省略
    }
}

		

タブの上にMusicアプリで見るようなViewを表示する

Apple標準のMusicアプリをみると、再生プレイヤーがタブの上に配置され、画面をスクロールするとタブと同列になって収まりのよい挙動をします。

似たような機能を実装をするには、tabViewBottomAccessory(content:)を使用します。

https://developer.apple.com/documentation/swiftui/view/tabviewbottomaccessory(content:)

このcontentの中に表示したいViewを渡します。

デモ

すでにスクロールするとタブが最小化する機能を実装しているので、スクロールすると、タブが最小化され、タブと検索タブの間にHello, Liquid Glass!と表示されたViewが移動します。

https://www.youtube.com/watch?v=KZ_4MEQIM-0

コード

			
			struct ContentView: View {
    @State var searchText = ""

    var body: some View {
        TabView {
            // ... 省略
        }
        .tabBarMinimizeBehavior(.onScrollDown)
        // ここを追加
        .tabViewBottomAccessory {
            Text("Hello, Liquid Glass!")
        }
    }
}

		

タブバーと並んだ時に表示を変更する

tabViewBottomAccessoryで表示したViewですが、タブの上部にある時は画面横いっぱいに表示されるのでスペースに困りませんが、タブと並ぶように配置された時はスペースに限りがあるので、表示の内容を変更したいという時があるかもしれません。

そんな時は、TabViewBottomAccessoryPlacementの値をEnvironmentで取得できるので、その値を使用してViewの要素を調整できます。

https://developer.apple.com/documentation/SwiftUI/TabViewBottomAccessoryPlacement

デモ

今回は、タブバーと並んで表示された場合に文字をHello!だけに変更しています。

https://www.youtube.com/watch?v=wPfgANjKFgw

コード

			
			struct ContentView: View {
    @State var searchText = ""

    var body: some View {
        TabView {
				    // ... 省略
        }
        .tabBarMinimizeBehavior(.onScrollDown)
        .tabViewBottomAccessory {
            // ここを変更
            BottomAccessoryView()
        }
    }
}

struct BottomAccessoryView: View {
    @Environment(\.tabViewBottomAccessoryPlacement) var placement

    var body: some View {
        switch placement {
        case .inline:
            Text("Hello!")
        default:
            Text("Hello, Liquid Glass!")
        }
    }
}

		

このTabViewBottomAccessoryPlacementは、以下の2つのケースがあります。

  • expanded
    • タブバー上に表示されている状態
  • inline
    • タブに並んで表示されている状態

ただ、この@Environment(\.tabViewBottomAccessoryPlacement)は、以下のようにオプショナルとなっているのでnilの時の判定が必要となります。

			
			extension EnvironmentValues {
    /// The current placement of the tab view bottom accessory.
    ///
    /// A `nil` value corresponds to an undefined placement.
    public var tabViewBottomAccessoryPlacement: TabViewBottomAccessoryPlacement? { get }
}

		

おわりに

Apple標準アプリが採用されているタブ表現の実装方法を理解することができました。

世の中のiOSアプリが順次Liquid Glassに対応していくことで、Appleの目指すユーザー体験により近づいていくと考えているので一歩ずつ対応を進めていきたいですね。

Liquid Glass対応を楽しみましょう。

この記事をシェアする

FacebookHatena blogX

関連記事

iOS 26からのLiquid Glassタブの実装を私もしたい | DevelopersIO