[SwiftUI] Toolbar の整理

SwiftUI

ツールバーが肥大化した時の 整理方法 を説明します。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Big Sur 11.2.2
  • Xcode 12.4
  • iOS 14.4

.toolbar の肥大化

アプリの機能を充実させていくと、Toolbar が肥大化してきます。

UNDO/REDO, Edit ボタン、・・・ View の本体と同じくらいの長さになることも。

Toolbar の整理方法を説明します。

長い .toolbar の例

以下の例を使います。別記事向けに書いている TODO アプリのビューですが、ビュー本体よりも、toolbar の記述の方が長くなってます。

長い toolbar の例

機能的には、NavigationBar の左上に Edit ボタン、右上に 追加の + ボタン。
BottomBar には、UNDO/REDO のボタンを追加しているコードです。

普通に必要になりそうな機能なのですが、それだけで、toolbar は、こんなに長くなってしまいます。

39行の body のうち、21行が toolbar の記述です。toolbar はある意味定型文なので、不必要に長いとコードの見通しが悪くなりメンテナンス性が下がってしまいます。

ToolbarItem の切り出し

どう切り出すかは、その後どのように再利用するかという設計依存ですが、ここでは、「左上に表示される EditButton 」として、切り出してみます。

カスタム ToolbarContent の定義

View を切り出して再利用できるのと同様に、Toolbar もカスタムな ToolbarContent を定義して再利用できます。

NavBarLeadingEdit
“var body” は同じですが、型は “some View” ではなく “some ToolbarContent” になります。

使用する側のコードは、以下のようになります。

少し短くなった toolbar

NavBarLeadingEdit として、別のビューでも簡単に再利用することができます。

struct 内変数として定義する Toolbar

外部に struct として切り出すまでも無い時には、struct の内部変数として定義することもできます。

例えば、現在のビューにしか関連しない 要素追加ボタンは、struct にしてもあまり再利用しない気がします。
このような時には、(Viewの) struct の内部変数にまとめてしまうこともできます。

UNDO/REDO も同様に内部変数にまとめました。

struct の内部変数としての ToolbarContent

上記の変数を使う側は以下のようになります。

example

struct の内部変数として定義すると、「別ビューでの再利用は難しい」というデメリットがありますが、「必要な情報には、そのままアクセスできる」というメリットもあります。

Toolbar 定義をまとめた最終形

カスタム ToolbarContent 定義と struct 内変数として定義した ToolbarContent を組み合わせたコードは、以下のようになります。

短くなった Toolbar 定義を持つ View

全体で考えるとコードが少なくなってはいませんが、ビューの body 部分は、39行もあった body が 22行にまで減り、ずいぶん見通しがよくなりました。

注意
外部 struct 定義した ToolbarContent は、@State や @ObservedObject からの変更通知を受け取ってアップデートされることはないようです。

ビュー struct 内部に定義されていると、ビューと合わせてアップデートされますが、外部 struct 化すると変更は伝播されないようです。
(2021.3.8 時点)

まとめ:toolbar のまとめ方

toolbar のまとめ方
  • struct MyOwnToolbar: some ToolBarContent として、カスタムツールバーを定義する
  • var myownToolbar: some ToolbarContent として、ビュー内で、カスタムツールバーを定義する

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です