SwiftUIでBottomToolbarを作る


今回作成する画面


今回は下にタブが5つあり、各タブをタップすると画面が切り替わるUIを作成します。
5つ画面用のViewを用意して違いがわかるようにします。
サンプルは以下のリポジトリに格納していますので参考にしてください。

https://github.com/chieta063/ToolbarSample

環境

  • MacOS: Monterey
  • Xcode: 13.3
  • iOS: 15.4

準備

サンプルのリポジトリをcloneするか、ContentViewの他に画面用のViewを5つ用意します。

実装

まずは今どの画面を表示しているかわかるように状態のenumを作成します。

enum ViewType {
  case first
  case second
  case third
  case fourth
  case fifth
}

次に作成したenumのStateをContentViewに追加します。

@State var currentView: ViewType = .first

今回はContentViewに直接Stateを設定していますが複雑なアプリではObservableObjectに作成してViewで参照するようにしたほうがベターです。
次は実際に表示するUIを実装します。

ZStack {
  switch currentView {
  case .first:
    FirstView()
  case .second:
    SecondView()
  case .third:
    ThirdView()
  case .fourth:
    FourthView()
  case .fifth:
    FIfthView()
  }
}

ZStackで一まとまりのViewを作成してその中でViewTypeによって表示する画面を切り替えます。
最後にBottomToolbarを作成し、各タブのタップイベントの中で現在表示しているViewの状態を切り替えます。
サンプルでは現在表示中のタブを青色で表示し押せなくして、他のタブは灰色で表示しています。

.toolbar {
  ToolbarItemGroup(placement: .bottomBar) {
    Button {
      currentView = .first
    } label: {
      Text("1").foregroundColor(isFirstSelected ? Color.blue : Color.gray)
    }
    .disabled(isFirstSelected)
    Spacer()
    Button {
      currentView = .second
    } label: {
      Text("2").foregroundColor(isSecondSelected ? Color.blue : Color.gray)
    }
    .disabled(isSelected(currentView: currentView, targetView: .second))
    Spacer()
    Button {
      currentView = .third
    } label: {
      Text("3").foregroundColor(isThirdSelected ? Color.blue : Color.gray)
    }
    .disabled(isSelected(currentView: currentView, targetView: .third))
    Spacer()
    Button {
      currentView = .fourth
    } label: {
      Text("4").foregroundColor(isFourthSelected ? Color.blue : Color.gray)
    }
    .disabled(isSelected(currentView: currentView, targetView: .fourth))
    Spacer()
    Button {
      currentView = .fifth
    } label: {
      Text("5").foregroundColor(isFifthSelected ? Color.blue : Color.gray)
    }
    .disabled(isSelected(currentView: currentView, targetView: .fifth))
  }
}

最後に

UIKitでは結構面倒だったBottomToolbarも簡単に作成でき、コード量も少なく実装できました。
SwiftUIはまだまだできることが少ないですがこれからの進化が楽しみですね!