【SwiftUI】toolbarの使い方!アイテムにボタンを増やす方法
この記事からわかること
- SwiftUIでtoolbarモディファイアの使い方と実装方法
- ナビゲーションバーやキーボードにボタンを増やすには?
- ToolbarItemPlacement構造体のプロパティ一覧
- ToolBarItemとToolbarItemGroupの使い方
- 子ビューのナビゲーションバーにボタンを表示するには?
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
Swift UIで簡単にツールバーを設置できるtoolbarモディファイアの使い方とボタンの実装方法などをまとめていきたいと思います。
toolbarモディファイアとは?
toolbar
モディファイアとはSwift UIに組み込まれているiOS14以降から使用可能なモディファイアの1つです。toolbar
モディファイアで使用することでNavigationViewの上部や下部、キーボードなどにツールバーを生成し、ボタンなどのViewを表示させることができます。
主にNavigationView
で囲われている時に使用するtoolbar
モディファイアですが、iOS15以降からkeyboardへの設置が追加されたのでNavigationViewの外側でも使用可能になっています。
toolbar
モディファイアはToolBarItem
構造体などと組み合わせて使用し、toolbar
モディファイアの中にToolBarItem
構造体を定義してボタンなどを設置します。
NavigationViewへの使い方
ツールバーを設置するにはNavigationView
で囲われている子要素に対してtoolbar
モディファイアを使用します。
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("要素1")
Text("要素2")
} .navigationTitle("タイトル")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
print("設定ボタンです")
}) {
Image(systemName: "gearshape.fill")
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
print("マイページです")
}){
HStack {
Image(systemName: "person.fill")
}
}
}
}
}
}
}
これだけで簡単に画面上部にボタンを設置することが可能です。
ToolbarItem構造体
toolbar
モディファイアの中ではToolbarItem
構造体を使用して Viewを設置します。イニシャライザとして引数placement
にはToolbarItemPlacement構造体を渡し、引数content
にボタンなどのViewを渡します。
ToolBarItem構造体のイニシャライザ
init(
placement: ToolbarItemPlacement = .automatic,
content: () -> Content
)
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
print("設定ボタンです")
}) {
Image(systemName: "gearshape.fill")
}
}
ToolbarItemPlacement構造体とは?
ToolbarItemPlacement
構造体のプロパティの値でツールバーを設置する場所を指定します。
配置する場所に指定できる値は3つの項目に分かれています。
3つのプロパティ項目
- explicit placement(明示的な配置位置)
- semantic placement(意味合い的な配置位置)
- placement for specific actions(アクションで見る配置位置)
explicit placement(明示的な配置位置)
iOSアプリを開発する際は基本的にこの項目の値を指定すればOKです。
プロパティ | 説明 |
---|---|
.navigationBarLeading | ナビゲーションバーの左端 |
.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の位置の調整がしにくいのでそれぞれのメリットデメリットを見ながら使うのがおすすめです。
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("要素1")
Text("要素2")
} .navigationTitle("タイトル")
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
Button(action: {
print("設定ボタンです")
}) {
Image(systemName: "gearshape.fill")
}
Button(action: {
print("マイページです")
}){
HStack {
Image(systemName: "person.fill")
}
}
}
}
}
}
}
子ビューのナビゲーションバーに表示する
NavigationLink
などで親ビューから子ビューへ遷移した場合は「Back」ボタンが子ビューのナビゲーションバーの中に自動で実装されます。
ここで子ビュー上でもツールバーを設置したい場合は既存の「Back」ボタンが不要になる場合があると思います。その際は子ビュー側ににnavigationBarBackButtonHidden
モディファイアを使えば非表示にすることができます。
struct ChildView: View {
var body: some View {
Text("ChildView")
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
print("設定ボタンです")
}) {
Image(systemName: "gearshape.fill")
}
}
}
}
}
ナビゲーションバー自体を非表示にするnavigationBarHidden
モディファイアもありますがこちらを使うと設置したツールバーも非表示になってしまうので注意してください。
keyboardへの使い方
NavigationView
とは関係なくキーボード部分にツールバーを設置することもできます。
使い所としては「TextFieldにkeyboardType(.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 // フォーカスを外す
}
}
}
}
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。