はじめに

WWDC 2026 で SwiftUI のツールバー周りが強化され、「画面幅が足りないときに、どの項目を残し、どれを畳むか」を開発者が制御できるようになりました。本記事では新APIの全体像を押さえたうえで、その中核である visibilityPriority を実際にシミュレータで動かし、挙動の違いを確認します。

検証環境:Xcode 27 beta 3 / iOS 27(シミュレータ/iPad A16)。WWDC 直後のベータAPIはビルド間でシンボル名や挙動が変わることがあります。本記事は上記時点での確認結果です。

WWDC 2026 で追加された新ツールバーAPI

iOS 27 で新しく入ったのは次の4つです。

  1. visibilityPriority(_:) — スペースが足りないとき、どの項目グループを優先して残すかを .high / .automatic / .low で宣言する
  2. ToolbarOverflowMenu — 低頻度の操作を、明示的に「…」オーバーフローメニューへまとめて格納する
  3. .topBarPinnedTrailing — 共有ボタンなど常に触れてほしい操作を、トップバーの右端に固定する
  4. toolbarMinimizeBehavior(_:for:) — スクロールに連動して、ナビゲーションバーやタブバーなどを自動で最小化する

この記事では1つ目の visibilityPriority を掘り下げます。

visibilityPriority とは

ツールバーの幅が足りなくなったときに、「どの項目グループから先に畳むか」をSwiftUIに教える優先度指定です。

  • 付ける対象は ToolbarItemGroup などのツールバー項目(優先度の型は ToolbarItemVisibilityPriority
  • 指定値は .high / .automatic(デフォルト) / .low(型の定義は公式ドキュメント(visibilityPriority(_:))を参照)
  • スペースが足りなくなると、SwiftUI は優先度の低いグループから順にオーバーフロー(…)へ畳む(詳しい順序は後述の検証を参照)

ポイントは「全部を必ず表示する」ではなく、「残す優先順位を宣言する」ところです。

何が畳む順番を決めているか(シミュレータで検証)

.high / .automatic / .low の関係は「高 > 中 > 低」と思いがちですが、シミュレータで複数パターンを試すと優先度だけでは決まらないことが分かりました。3グループ(A / B / C、各2ボタン、placement 指定なし)を用意し、優先度と「書いた順(宣言順)」を変えながら、幅を狭めて畳まれる順を観察しました。

#構成(宣言順・上から)畳まれた順
1A / B / C すべて .automaticC → B(A が残る)
2内容は1と同じで書く順だけ C / B / AA → B(C が残る)
3A=.high / B=.automatic / C=.lowC → B(A が残る)
4A=.low / B=.automatic / C=.highB → A(C が残る)
5A=.low / B=.low / C=.highB → A(C が残る)

ここから読み取れる決定ルールは次の3点です。

  1. .high は必ず最後まで残る(優先度が宣言順に勝つ)。 パターン4・5では、.high を付けた C を一番下に書いても残りました。「後に書いたものが先に畳まれる」よりも .high の保護が強い、ということです。
  2. 同じレベル内では、後に書いたグループほど先に畳まれる(宣言順がタイブレーク)。 パターン1(C→B)と、書く順を逆にしたパターン2(A→B)で消える側も入れ替わりました。パターン5でも同じ .low の A・B のうち後に書いた B が先に消えています。
  3. .low.automatic に固有の差は観測できなかった。 パターン3では .low.automatic より先に、パターン4では逆になりましたが、どちらも「後に書いた方が先」で説明でき、低いか自動かによる差は見られませんでした。

まとめると挙動は「まず優先度(.high を保護)→ 同順位は宣言順で、後に書いたものから畳む」です。

⚠️「.automatic.high.low の中間」という理解は正確ではありません。少なくとも検証したビルドでは、.automatic.low の差は宣言順の効果でしか説明できませんでした。確実に残したいものには .high を明示し、消える順は書く順で調整するのが実務上の指針になります。

なお、これらは検証時点のベータでの観測結果です。挙動は正式版までに変わる可能性があるため、重要な UI では自分の環境でも確認してください。

デモアプリ

ステッカー編集画面を題材に、優先度の異なる2つのグループを用意しました。

.toolbar {
    // ★ 高優先度グループ:幅が狭くても最後まで残る
    ToolbarItemGroup {
        Button { model.undo() } label: {
            Label("Undo", systemImage: "arrow.uturn.backward")
        }
        .disabled(!model.canUndo)

        Button { model.redo() } label: {
            Label("Redo", systemImage: "arrow.uturn.forward")
        }
        .disabled(!model.canRedo)
    }
    .visibilityPriority(.high)   // ← 高

    // ★ 低優先度グループ:スペースが足りないと先に「…」へ畳まれる
    ToolbarItemGroup {
        Button { model.addSticker() } label: {
            Label("Add", systemImage: "plus.circle")
        }
        Button { model.shuffle() } label: {
            Label("Shuffle", systemImage: "shuffle")
        }
        Button(role: .destructive) { model.clearAll() } label: {
            Label("Clear", systemImage: "trash")
        }
    }
    .visibilityPriority(.low)    // ← 低

    // 共有ボタンは常に右端へピン留め
    ToolbarItem(placement: .topBarPinnedTrailing) {
        ShareLink(item: "My stickers!") {
            Label("Share", systemImage: "square.and.arrow.up")
        }
    }
}

Undo/Redo.highAdd/Shuffle/Clear.low にしています。

シミュレータでの確認方法

ツールバーは横幅が足りないときに項目を畳むので、幅を意図的に狭めるのがコツです。次のいずれかで再現できます。

  • iPadシミュレータ + Split View / Slide Over(おすすめ):アプリを狭いカラムに寄せると、幅に応じて畳まれる
  • Xcode 27 の Device Hub でウィンドウを動的リサイズ:ドラッグで縮めるとその場で畳まれる

見るべき場所

ナビゲーションバーの右上です。この2グループのデモ(Undo/Redo=.high、Add系=.low)では、幅を狭めていくと——

  • .low グループ(Add / Shuffle / Clear)が先に「…」メニューに畳まれる
  • .high グループ(Undo / Redo)は最後まで残る

優先度を入れ替えてみる

効果を一番分かりやすく確かめるには、優先度を逆転させるのがおすすめです。両方を .high にしても、スペースに余裕があると見た目が変わらず、違いが分かりにくいです。一方、優先度を入れ替えると挙動がはっきり反転します。

本来なら残したい Undo/Redo をあえて .low、二次的な Add/Shuffle/Clear.high にします。

// Undo/Redo をあえて低に
ToolbarItemGroup {
    // Undo / Redo ...
}
.visibilityPriority(.low)

// Add/Shuffle/Clear をあえて高に
ToolbarItemGroup {
    // Add / Shuffle / Clear ...
}
.visibilityPriority(.high)

すると幅を狭めたとき、普段は残ってほしい Undo/Redo の方が先に「…」へ畳まれ、二次的な Add 系が残るという逆転が起きます。先ほどの .high/.low 版と見比べると、畳まれるグループが入れ替わるのが一目で分かります。

このように、少なくとも .high.low の間では「高い方が残り、低い方から畳まれる」順序をコード側でコントロールできます(.automatic を含めた細かい順序は前述の検証を参照)。

今まで(このAPIが無かった頃)はどうだったか

iOS 26 以前は、畳む順番を開発者が指定できませんでした。

  • 項目が入り切らないと、SwiftUIが自動で一部を「…」メニューに落とす
  • 回避するには項目の並べ替えや、horizontalSizeClass などで自前で条件分岐して表示を切り替える必要があった

visibilityPriority の登場で、「重要度を宣言しておけば、狭いときはシステムが重要なものを残してくれる」という宣言的な制御に変わりました。

まとめ

  • visibilityPriority は、ツールバーが狭いときに残す優先度を宣言する新API(iOS 27)
  • 検証では .high が最優先で保護され、.low.automatic に差は出ず、同順位は後に書いたグループから畳まれた(宣言順がタイブレーク)
  • 以前はシステム任せで制御できなかった部分を、宣言的にコントロールできるようになった

新APIは他にも ToolbarOverflowMenu / .topBarPinnedTrailing / toolbarMinimizeBehavior があり、組み合わせるとリサイズ対応のツールバー設計がほぼカバーできます。


参考リンク



ギャップロを運営しているアップフロンティア株式会社では、一緒に働いてくれる仲間を随時、募集しています。 興味がある!一緒に働いてみたい!という方は下記よりご応募お待ちしております。
採用情報をみる