[SwiftUI] .presentationMode で非表示を管理した方が良いケース

SwiftUI

@Environment(\.presentationMode) の使用が必須となるケースを説明します。

presentationMode は、あまり使いたくありませんでした

SwiftUI[SwiftUI]Sheetの閉じかた:Environmentの.presentationModeより@Bindingを渡して行う表示制御が自然に思える

上記でも書いたのですが、@Environment の .presentationMode を使うのはあまり良くないと考えて、できるだけ引数渡ししていました。

引数渡しが難しいケースがあったので、説明します。

NavigationLink を例に

NavigationLink には、複数の initializer がありますが、表示を制御する変数を渡せるものも以下の initializer のように存在します。

NavigationLink initializer

init(destination: Destination, isActive: Binding, label: () -> Label)

ですので、NavigationLink が1つであれば、isActive に変数を渡すことで、問題なく管理することができます。

表示制御変数を 事前定義することが難しいケース

例えば、List/ForEach で不特定多数の行を作成し、個々の行からウィンドウを開閉するようなケースです。

NavigationLink を使うと、以下のようなコードになるはずです。

example

    @State var items = ["item1", "item2", "item3", "item4", ....]
    var body: some View {
        NavigationView {
            List {
                ForEach(items, id:\.self) { item in
                    NavigationLink(
                        // (1)
                        destination: ChildView(isPresented: ???, text: item),
                        // (2)
                        isActive: ???,
                        label: {
                            Text("Navigate to ChildView \(item)")
                        })
                        .padding()
                }
            }
        }
    }

(1) と (2) の ??? には、同一の Binding 変数を渡す必要があります。
問題は、(1) の箇所に渡す変数をどうするかです。

技術的には、ForEach に合わせて 変数を作り、それを配列等に保存しておくことも可能ですが、不必要に複雑化している気がします。

ということで、List, ForEach 等で不特定多数の行を作りそこから別ビューにジャンプするような時には、表示制御用の変数を渡すよりも、presentationMode を使う方が、シンプルになることがわかりました。

まとめ:presentationMode を使う方が良いケース

presentationMode を使う方が良いケース
  • 不特定多数の ビュー表示を制御する必要があるとき
注意
(iOS14.2 時点) おそらく iOS のバグですが、presentationMode を使って表示したシートから復帰すると、NavigationBar の Toolbar ボタンがおかしくなります。
NavigationView を含むビューに、@Environment(\.presentationMode) var presentationMode と定義しておくと、回避することが可能です。

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

コメントを残す

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