Open2

SwiftUI: SheetとNavigationLinkの使い分けを考える

kabeyakabeya

次のページを表示する方法として、シートとナビゲーションの2つがあります。

シートはいまのページの上に新たなページが表示されるイメージ、ナビゲーションはいまのページの右に新たなページができてそっちにスライドして移動するようなイメージです。

SwiftUIでは以下の方法で実現します。

  • シート:.sheetモディファイアで実現可能
  • ナビゲーション:NavigationView/NavigationStackとNavigationLinkで実現可能
    NavigationLinkは使わなくても.navigationDestinationモディファイアでも実現できる

どういうケースで、どちらの手法を使うべきなのか悩んでいます。

それぞれの手法の特徴

特徴を改めてまとめます。

  • シート
    • モーダル。閉じるまでは他の操作ができない。
    • 閉じるためのボタン(「キャンセル」「閉じる」や「保存」)を付ける必要あり
      なくても閉じられるけども、閉じ方自体も分かりにくいし、閉じたときに何が起こるのかも分かりにくい。
      (ボタンを使わずに閉じたときは基本的には「キャンセル」と同じと思いますが)
    • タブバーやナビゲーションバーがあっても覆い隠す。
  • ナビゲーション
    • モードレス?モーダル?
    • 戻るボタン(というか前の画面へのリンクボタン)が勝手に表示される。
      なので、もし「キャンセル」や「保存」ボタンを付けると「戻る」のときに何が起こるかが分かりにくい。
    • タブバーやナビゲーションバーがある場合、覆い隠さない。というか遷移元のビューと差し替わる格好で表示される。
    • 右に移動するアニメーションが表示されるので(アラビア語圏だとたぶん逆で、左に移動する)、階層をたどるような印象になる。

なにを主体に判断するか

こうやって書くと、「キャンセル」「保存」が必要かどうかが重要な気がします。
キャンセルが必要な場合はシート。
逆にナビゲーションの場合は、キャンセルで戻るだとおかしいように思えます。
階層をたどり、必要に応じてそこで編集ボタン(Edit)を押して、完了(Done)にして戻る、というようなイメージですね。

もとの画面でのアイテムというか状況というか、それごとに表を作れるかもしれません。
(これが正解というわけではないです。いまふとまとめたらこうなりそう、というだけ)

もとの画面のアイテム/状況 次のページの内容 利用する遷移
アイテムの概要・見出し アイテムの詳細の確認・編集 ナビゲーション
新規アイテム追加ボタン 新規アイテムの編集 シート
既存アイテム編集ボタン 既存アイテムの編集 シート
設定項目 設定可能な候補のリスト ナビゲーション[1]
脚注
  1. とは言え単純な文字列での候補一覧なら、ページを作るよりはDisclosureGroupを使ったインラインメニューのようなものにしたほうが良さそう ↩︎

kabeyakabeya

今日、アップルのアプリでナビゲーションで次の画面に移った際、ナビゲーションツールバーの「前の画面戻る」の反対側に「キャンセル」がありました。

キャンセルのみの場合はそれでもいいのかな。