feed

2021年08月26日, 編集履歴

SwiftUIでDocument-Based Appな画像閲覧アプリを作る その3 ツールバーの実装

SwiftUIでDocument-Based Appな画像閲覧アプリ習作の覚書その3。PNG/JPEG画像を開いて閲覧、スクロール、ピンチジェスチャで拡大縮小、ツールバーにボタン配置等を実装した。

このシリーズの他のブログは、

作成したプロジェクトはGitHubで公開している。

ビルド環境は、

である。

前回、表示した画像をジェスチャで拡大縮小できるようにした。今回はツールバーを実装する。

ツールバーの実装

ビューに対してtoolbar(content:)を付与すると、ツールバーをつけることができる。引数contentにはToolbarContentに適合したオブジェクト、具体的にはToolbarItemToobarItemGroupを与える。

var body: some View {

  ScrollView([.horizontal, .vertical]) {
    ...
  }
  .toolbar {
    ToolbarItem {
      Button("Button 1") { ... }
    }
    ToolbarItemGroup {
      Button("Button 2") { ... }
      Button("Button 3") { ... }
    }
  }
}

のような感じ。toolbar(content:)の中に適当に要素を列挙していけばよいが、長くなると本来のビューの構造が解りづらくなるので、今回はサブビュー化する方針を採った。

struct ContentView: View {

  ...

  var body: some View {

    ScrollView([.horizontal, .vertical]) {
      ...
    }
    .toolbar {
      MagnifyToolbarButtons(document: self.document)
    }
  }
}

struct MagnifyToolbarButtons: ToolbarContent {

  let document: ImageDocument

  var body: some ToolbarContent {

    #if os(iOS)
    let placement = ToolbarItemPlacement.bottomBar
    #else
    let placement = ToolbarItemPlacement.automatic
    #endif
    ToolbarItemGroup(placement: placement) {
      Button(action: {
        self.document.scaleViewSize(0.5, animate: true)
      }) {
        Image(systemName: "minus.magnifyingglass")
      }
      Button(action: {
        self.document.resetViewSize(animate: true)
      }) {
        Image(systemName: "equal.circle")
      }
      Button(action: {
        self.document.scaleViewSize(2.0, animate: true)
      }) {
        Image(systemName: "plus.magnifyingglass")
      }
    }
  }
}

このとき、サブビューの構造体とそのbodyプロパティはToolbarContentに適合させるようにする。

また、iPhoneの場合、画面上部のツールバーに複数のボタンを配置しても最初のひとつしか表示されないため、画面下部のツールバーに表示させるようOSによる場合分けを行なった。