この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
SwiftUIでToolbarItemを.bottomBar
に複数配置した場合にアイテムを中央に配置する方法を調べたので記載しておきます。
環境
- Xcode 14.2
- iOS 16.1
アイテムをbottomBarに配置した挙動
アイテムが1点のみの場合は中央に配置される
ToolbarItemPlacement
を.bottomBar
に指定した場合は、デフォルトで中央に配置されます。
struct ToolbarCenterView: View {
var body: some View {
NavigationStack {
Text("I want the toolbar to be centered.")
.toolbar {
ToolbarItem(placement: .bottomBar) {
Text("center")
}
}
}
}
}
アイテム2点を追加すると両端に配置される
struct ToolbarCenterView: View {
var body: some View {
NavigationStack {
Text("I want the toolbar to be centered.")
.toolbar {
ToolbarItem(placement: .bottomBar) {
Text("center")
}
ToolbarItem(placement: .bottomBar) {
Image(systemName: "plus")
}
}
}
}
}
bottomBarの中央にアイテムを配置する
statusを指定したアイテムは中央に配置される
ToolbarItemPlacement
を.status
に指定した場合は、デフォルトで中央に配置されます。
status
のドキュメントにもそのことが明記されています。
ステータス項目は本質的に情報提供を目的としており、ユーザーが実行できるアクションを表すものではありません。たとえば、新しいメッセージを確認するためにサーバーと最後に通信した時刻を示すメッセージです。
iOS および iPadOS では、システムはステータス項目を下部ツールバーの中央に配置します。
引用: Apple Developer Documentation - status
struct ToolbarCenterView: View {
var body: some View {
NavigationStack {
Text("I want the toolbar to be centered.")
.toolbar {
ToolbarItem(placement: .status) {
Text("center")
}
ToolbarItem(placement: .bottomBar) {
Image(systemName: "plus")
}
}
}
}
}
.status
以外のToolbarItem
が.bottomBar
にある場合- 1点ある場合、そのアイテムは強制的に左側に配置される
- 2点ある場合、そのアイテムは両端に配置される
Spacerを使用してアイテムを中央に配置する
SpacerのToolbarItemを使用する方法
愚直にToolbarItem(placement: .bottomBar)
にSpacer()
を追加して配置する方法です。配置は出来ましたが、コードが冗長な気がします。
struct ToolbarCenterView: View {
var body: some View {
NavigationStack {
Text("I want the toolbar to be centered.")
.toolbar {
ToolbarItem(placement: .bottomBar) {
Spacer()
}
ToolbarItem(placement: .bottomBar) {
Text("center")
}
ToolbarItem(placement: .bottomBar) {
Spacer()
}
ToolbarItem(placement: .bottomBar) {
Image(systemName: "plus")
}
}
}
}
}
ToolbarItemGroupを使用する方法
上記のSpacerのToolbarItemを使用する方法だと少し冗長になってしまいます。ToolbarItemGroup
を使用することで、Toolbarに配置するアイテムをグループ化することが出来ます。
struct ToolbarCenterView: View {
var body: some View {
NavigationStack {
Text("I want the toolbar to be centered.")
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
Spacer()
Text("center")
Spacer()
Image(systemName: "plus")
}
}
}
}
}
HStackを使用する必要がない
最初下記のように記述して、「あれ?描画されないな」となってしまいました。
ToolbarItemGroup(placement: .bottomBar) {
HStack {
Spacer()
Text("center")
Spacer()
Image(systemName: "plus")
}
}
ToolbarItemGroup
内のコンポーネントは上から順に左から配置されるので特にHStack
を使用する必要はありません。
まとめ
- bottomBarに配置するアイテムが1点のみで中央の場合は
.status
を使用するのが良さそう - ひとつの
ToolbarItemPlacement
に複数のアイテムを配置する際はToolbarItemGroup
で集約出来る ToolbarItemGroup
内のコンポーネントはHStack
使用しなくても左から配置される
おわりに
まだまだToolbarItemPlacement
は他にもあるので色々触って遊んでみたいと思います。