toolbars について
SwiftUIのツールバーパターンを扱う開発者向けガイドです。カスタマイズ、検索連携、システム項目の配置、トランジションに加え、iOS、iPadOS、macOSの違いとAPIの利用条件を説明します。
主な機能
- 01カスタマイズ可能な項目の追加
- 02検索動作と配置の設定
- 03システムツールバー項目の移動
- 04ツールバーのトランジション作成
- 05プラットフォーム差とAPI条件の確認
活用シーン
- 01アプリにユーザー設定可能なツールバーを追加
- 02検索欄を適切な位置へ移動
- 03ツールバーボタンからズーム遷移を追加
- 04プラットフォーム間のレイアウトを確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ rshankras/ claude-code-apple-skills --skill toolbarsインストール後、Claude Code で/toolbarsを入力して読み込まれたか確認します。
詳細
SwiftUI ツールバー
SwiftUI アプリ向けの最新のツールバーパターンです。カスタマイズ可能なツールバー、強化された検索機能との連携、新しい配置、トランジション効果、プラットフォーム固有の考慮事項を扱います。
このスキルが有効になる場合
次のような場合にこのスキルを使用します。
- ツールバーを追加またはカスタマイズしたい
- カスタマイズ可能/ユーザー設定可能なツールバーについて質問したい
- 特定の位置に検索フィールドを配置する必要がある
- ツールバー項目のトランジションやアニメーションを使いたい
- ツールバーの配置(bottomBar、largeSubtitle など)について質問したい
- プラットフォーム固有のツールバーの動作(iOS と macOS)を確認したい
- システムのツールバー項目(検索、サイドバー)を再配置したい
判断ツリー
What toolbar feature do you need?
|
+- User-customizable toolbar (add/remove/reorder items)
| +- Use .toolbar(id:) with ToolbarItem(id:)
|
+- Search field in toolbar
| +- Minimize to button -> .searchToolbarBehavior(.minimize)
| +- Reposition search -> DefaultToolbarItem(kind: .search, placement:)
|
+- Toolbar transition/animation
| +- Zoom transition from toolbar item -> .matchedTransitionSource(id:in:)
| +- Hide glass background -> .sharedBackgroundVisibility(.hidden)
|
+- Custom subtitle area content
| +- Use ToolbarItem(placement: .largeSubtitle)
|
+- System toolbar items with custom placement
| +- DefaultToolbarItem(kind: .search/.sidebar, placement:)
API の利用可能状況
| API | 最小バージョン | 備考 |
|---|---|---|
.toolbar { } | iOS 14 | 基本的なツールバー |
ToolbarItem(placement:) | iOS 14 | 標準の配置 |
.toolbar(id:) | iOS 16 | カスタマイズ可能なツールバー |
ToolbarItem(id:) | iOS 16 | カスタマイズ可能なツールバー内の項目 |
ToolbarSpacer | iOS 16 | 固定および可変のスペーサー |
.searchable() | iOS 15 | 検索機能との連携 |
.searchToolbarBehavior(.minimize) | iOS 17 | 最小化された検索ボタン |
DefaultToolbarItem(kind:placement:) | iOS 18 | システム項目を再配置 |
ToolbarItem(placement: .largeSubtitle) | iOS 18 | サブタイトル領域のコンテンツ |
.matchedTransitionSource(id:in:) | iOS 18 | ツールバーのトランジション元 |
.sharedBackgroundVisibility() | iOS 18 | ガラス背景の制御 |
カスタマイズ可能なツールバー
ユーザーがツールバー項目を追加、削除、並べ替えて、ツールバーを自分好みに設定できるようにします。
ContentView()
.toolbar(id: "main-toolbar") {
ToolbarItem(id: "tag") {
TagButton()
}
ToolbarItem(id: "share") {
ShareButton()
}
ToolbarSpacer(.fixed)
ToolbarItem(id: "more") {
MoreButton()
}
}
ツールバースペーサー
ToolbarSpacer(.fixed) // Fixed-width space
ToolbarSpacer(.flexible) // Flexible space — pushes items apart
避けるべきパターン
// ❌ Missing IDs in customizable toolbar — items can't be customized
.toolbar(id: "main") {
ToolbarItem { // No id parameter
ShareButton()
}
}
// ✅ Every item needs its own ID
.toolbar(id: "main") {
ToolbarItem(id: "share") {
ShareButton()
}
}
強化された検索機能との連携
最小化された検索
検索フィールドをコンパクトなボタンとして表示し、タップすると展開します。
@State private var searchText = ""
NavigationStack {
RecipeList()
.searchable(text: $searchText)
.searchToolbarBehavior(.minimize)
}
検索の再配置
デフォルトの検索フィールドを別のツールバー位置に移動します。
NavigationSplitView {
AllCalendarsView()
} detail: {
SelectedCalendarView()
.searchable(text: $query)
.toolbar {
ToolbarItem(placement: .bottomBar) {
CalendarPicker()
}
ToolbarItem(placement: .bottomBar) {
Invites()
}
DefaultToolbarItem(kind: .search, placement: .bottomBar)
ToolbarSpacer(placement: .bottomBar)
ToolbarItem(placement: .bottomBar) {
NewEventButton()
}
}
}
システム定義のツールバー項目
カスタムの配置を指定してシステム項目を再配置します。
.toolbar {
DefaultToolbarItem(kind: .search, placement: .bottomBar)
DefaultToolbarItem(kind: .sidebar, placement: .navigationBarLeading)
}
大きなサブタイトルの配置
ナビゲーションバーのサブタイトル領域にカスタムコンテンツを配置します。
NavigationStack {
DetailView()
.navigationTitle("Title")
.navigationSubtitle("Subtitle")
.toolbar {
ToolbarItem(placement: .largeSubtitle) {
CustomLargeNavigationSubtitle()
}
}
}
トランジション効果
ツールバーからのマッチドトランジション
ツールバーボタンを起点とするズームトランジションを作成します。
struct ContentView: View {
@State private var isPresented = false
@Namespace private var namespace
var body: some View {
NavigationStack {
DetailView()
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Show Sheet", systemImage: "globe") {
isPresented = true
}
}
.matchedTransitionSource(id: "world", in: namespace)
}
.sheet(isPresented: $isPresented) {
SheetView()
.navigationTransition(
.zoom(sourceID: "world", in: namespace))
}
}
}
}
ガラス背景の制御
ツールバー項目の共有ガラス背景を制御します。
ContentView()
.toolbar(id: "main") {
ToolbarItem(id: "build-status", placement: .principal) {
BuildStatus()
}
.sharedBackgroundVisibility(.hidden)
}
よくある間違いトップ 5
| # | 間違い | 修正方法 |
|---|---|---|
| 1 | カスタマイズ可能なツールバー内の ToolbarItem に id がない | .toolbar(id:) 内の各項目に、それぞれ独自の id パラメーターを指定する必要があります |
| 2 | .searchable() を使わずに .searchToolbarBehavior(.minimize) を使用する | .searchable() モディファイアと組み合わせる必要があります。.minimize は表示方法にのみ影響します |
| 3 | .matchedTransitionSource を ToolbarItem ではなく Button に指定する | コンテンツではなく、ToolbarItem に .matchedTransitionSource(id:in:) を適用します |
| 4 | .navigationSubtitle() と併せて .largeSubtitle を使い、両方が表示されると期待する | .largeSubtitle が優先されるため、サブタイトルモディファイアの値は表示されません |
| 5 | DefaultToolbarItem に placement: を指定し忘れる | 明示的な配置を指定しないと、システム項目はデフォルトの位置を使用します |
プラットフォームに関する考慮事項
| プラットフォーム | 推奨事項 |
|---|---|
| iOS | iPhone ではボトムバーが便利です。省スペースのために .searchToolbarBehavior(.minimize) を使用します。 |
| iPadOS | カスタマイズ可能なツールバーは、生産性アプリで役立ちます。キーボードショートカットも検討してください。 |
| macOS | ユーザーはツールバーをカスタマイズできることを期待します。論理的なグループ分けにはスペーサーを使用します。 |
レビューチェックリスト
カスタマイズ可能なツールバー
-
.toolbar(id:)に一意で安定した文字列識別子が指定されている - 内部のすべての
ToolbarItemに、それぞれ独自のidが指定されている - 関連する項目を論理的にグループ化するためにスペーサーが使われている
- カスタマイズパネルを使ってツールバーをテストした(iPadOS では長押し、macOS では右クリック)
検索の統合
-
.searchable()に適切な.searchToolbarBehavior()を組み合わせている - 検索の配置がプラットフォームに適している(iOS では下部バー、macOS ではツールバー)
- 再配置が必要な場合は
DefaultToolbarItem(kind: .search)を使用している
トランジション
-
.matchedTransitionSourceをコンテンツビューではなくToolbarItemに適用している - 名前空間をビューのレベルで
@Namespaceを使って宣言している -
.matchedTransitionSourceと.navigationTransition(.zoom)の間でソース ID が一致している
プラットフォーム
- マルチプラットフォームの場合、iOS と macOS の両方でツールバーレイアウトをテストしている
- 画面の小さいデバイスに適した下部バーの項目を使用している
- 複雑な macOS アプリ向けにカスタマイズ可能なツールバーを用意している
参考資料
コメント
Markdown 対応