【Swift UI】toolbarの使い方!トップ・ボトム・キーボードにツールバーを実装する

【Swift UI】toolbarの使い方!トップ・ボトム・キーボードにツールバーを実装する

この記事からわかること

  • SwiftUItoolbarモディファイア使い方実装方法
  • ナビゲーションバーキーボードボタンを増やすには?
  • ToolbarItemPlacement構造体のプロパティ一覧
  • ToolBarItemToolbarItemGroup使い方
  • 子ビューのナビゲーションバーにボタン表示するには?

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Swift UIで簡単にツールバー(トップ(ナビゲーション)バーやボトムバー等)を設置できるtoolbarモディファイアの使い方とボタンの実装方法などをまとめていきたいと思います。またiOS26からLiquid Grassデザインが導入され大きくUIが変化したので注意してください。

toolbarモディファイアとは?

toolbarモディファイアとはSwift UIに組み込まれているiOS14以降から使用可能なモディファイアの1つです。toolbarモディファイアで使用することでNavigationの上部や下部、キーボードなどにツールバーを生成し、ボタンなどのViewを表示させることができます。

主にNavigationStackで囲われている時に使用するtoolbarモディファイアですが、iOS15以降からkeyboardへの設置が追加されたのでNavigationStackの外側でも使用可能になっています。

ツールバーの実装方法

ツールバーを設置するにはNavigationStackで囲われている子要素に対してtoolbarモディファイアを使用します。クロージャーの中でToolBarItem構造体を定義してボタンなどを設置しplacement設置位置を指定します。

【SwiftUI】NavigationViewの使い方!上部にツールバーを実装する
struct ContentView: View {
    var body: some View {
        NavigationStack {
            VStack {
                List {
                    Text("要素1")
                    Text("要素2")
                }
            }.navigationTitle("タイトル")
                .toolbar {
                    ToolbarItem(placement: .topBarLeading) {
                        Button {
                            print("設定ボタンです")
                        } label: {
                            Image(systemName: "gearshape.fill")
                        }
                    }
                    ToolbarItem(placement: .topBarTrailing) {
                        Button {
                            print("マイページです")
                        } label: {
                            HStack {
                                Image(systemName: "person.fill")
                            }
                        }
                    }
                }
        }
    }
}

例えばtopBarLeading/topBarTrailingと指定するだけで画面上部にボタンを設置することが可能です。ここからは中で使用するToolbarItem構造体などの使い方をまとめていきます。

ToolbarItem構造体

toolbarモディファイアの中ではToolbarItem構造体を使用してViewを設置します。イニシャライザとして引数placementにはToolbarItemPlacement構造体を渡し、引数contentボタンなどのViewを渡します。

ToolBarItem構造体のイニシャライザ

init(
    placement: ToolbarItemPlacement = .automatic,
    content: () -> Content
)
ToolbarItem(placement: .topBarLeading) {
    Button {
        print("設定ボタンです")
    } label: {
        Image(systemName: "gearshape.fill")
    }
}

ToolbarItemPlacement構造体

公式リファレンス:ToolbarItemPlacement構造体

ToolbarItemPlacement構造体はツールバーを設置する場所を定義するための構造体です。

配置する場所に指定できる値は3つの項目に分かれています。

3つのプロパティ項目

explicit placement(明示的な配置位置)

iOSアプリを開発する際は基本的にこの項目の値を指定すればOKです。

プロパティ 説明
.topBarLeading (.navigationBarLeadingは廃止) ナビゲーションバーの左端
.topBarTrailing (.navigationBarTrailingは廃止) ナビゲーションバーの右端
.bottomBar ボトムバー
.keyboard キーボード

配置できるのはナビゲーションバーの両端とボトムバー(下側)、そしてキーボードです。

semantic placement(意味合い的な配置位置)

semantic(セマンティック)」の言葉通り「意味合い」的に配置位置を指定します。

プロパティ 説明
.automatic アイテムが自動的に配置
.principal 主要なアイテムの配置
iOSではナビゲーションバーの中央
navigationTitleよりも優先
.status ステータス情報の表示位置
iOSではボトムバーの中央

placement for specific actions(アクションで見る配置位置)

プロパティ 説明
.primaryAction 主要なアクションの配置
iOSではナビゲーションバーの右端
.secondaryAction:ベータ版 二次的なアクションの配置
ベータ版
.confirmationAction 確認アクションの配置
iOSではprimaryActionと同じ
.cancellationAction キャンセルアクションの配置
iOSではナビゲーションバーの左端
.destructiveAction 破壊的アクションの配置
iOSではナビゲーションバーの右端
.navigation ナビゲーションアクションの配置
iOSではナビゲーションバーの左端または.primaryActionを指す。
.primaryAction 主要なアクションの配置。
iOSではナビゲーションバーの右端。

ToolbarItemGroup構造体

toolbarモディファイアの中にはToolbarItemだけでなくToolbarItemGroup構造体を使用することもできます。両者の違いは名称通り、1つずつ定義するか一括で定義するかの違いです。ToolbarItemGroupの中にView単位(ボタンなど)でアイテムを複数記述するだけでツールバー上に複数のViewを設置することができます。

ToolbarItemで複数設置したい場合はToolbarItemその個数分記述しなくてはいけないので可読性が下がってしまいます。とはいえToolbarItemGroupでは各Viewの位置の調整がしにくいのでそれぞれのメリットデメリットを見ながら使うのがおすすめです。

【Swift UI】toolbarの使い方!トップ・ボトム・キーボードにツールバーを実装する
.toolbar {
  ToolbarItemGroup(placement: .topBarLeading) {
      Button {
          print("設定ボタンです")
      } label: {
          Image(systemName: "gearshape.fill")
      }
      Button {
          print("マイページです")
      } label: {
          HStack {
              Image(systemName: "person.fill")
          }
      }
  }
}

子ビューのナビゲーションバーに表示する

NavigationLinkなどで親ビューから子ビューへ遷移した場合は「Back」ボタンが子ビューのナビゲーションバーの中に自動で実装されます。

ここで子ビュー上でもツールバーを設置したい場合は既存の「Back」ボタンが不要になる場合があると思います。その際は子ビュー側にnavigationBarBackButtonHiddenモディファイアを使えば非表示にすることができます。

struct ChildView: View {
  @Environment(\.dismiss) var dismiss
  var body: some View {

      Text("ChildView")
          .navigationBarBackButtonHidden(true)
          .toolbar {
              ToolbarItem(placement: .topBarLeading) {
                  Button {
                      dismiss()
                  } label: {
                      Image(systemName: "chevron.backward")
                  }
              }
          }
  }
}

ナビゲーションバー自体を非表示にするnavigationBarHiddenモディファイアもありますがこちらを使うと設置したツールバーも非表示になってしまうので注意してください。

keyboardへの使い方

NavigationStackとは関係なくキーボード部分にツールバーを設置することもできます。

使い所としては「TextFieldにkeyboardType(.numberPad)を指定時の閉じるボタンの実装」として用いることが多いです。詳細はこちらの記事で解説しております。

TextFieldでnumberPadのみ発生する閉じれない問題

keyboardへの実装をするには引数placementに「.keyboard」を指定するだけです。

struct ContentView: View {
  @State var milage:String = ""   
  @FocusState var isActive:Bool

  var body: some View {
      TextField("km", text: $milage)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .keyboardType(.numberPad)
            .focused($isActive)
            .toolbar {
                ToolbarItemGroup(placement: .keyboard) {
                    Spacer()         // 右寄せにする
                    Button {
                        isActive = false  //  フォーカスを外す
                    } label: {
                      Text("閉じる")
                    }
                }
            }
  }
}

ボトムバーを実装する

ボトムバーを実装したい場合はbottomBarを使用します。

【Swift UI】toolbarの使い方!トップ・ボトム・キーボードにツールバーを実装する
.toolbar {
    ToolbarItemGroup(placement: .bottomBar) {
        Button {
            print("設定ボタンです")
        } label: {
            Image(systemName: "gearshape.fill")
        }
        Button {
            print("マイページです")
        } label: {
            HStack {
                Image(systemName: "person.fill")
            }
        }
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

Search Box

Sponsor

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index