【Swift UI】dismissの使い方と注意点!子ビューと親ビュー

この記事からわかること
- Swift UIでnavigationViewの画面遷移をコントロールする方法
- dismissの使い方と注意点
- 画面を戻る際に子ビューだけで無く親ビューまで閉じる原因
index
[open]
\ アプリをリリースしました /
Swift UIでnavigationView
の戻るボタンを実装する際に使用するdismiss
の使い方と注意点をまとめていきます。
またNavigationViewの使い方に関しては 以下の記事を参考にしてください。
dismissとは?
dismissはNavigationView内でNavigationLinkで遷移したビューから戻る処理を実装するために使用できるプロパティです。dismissを翻訳すると「却下」や「解散」などの意味になります。
dismiss自体はロケールやカラースキームなどの環境値を保持するEnvironmentValues
構造体のインスタンスプロパティとして定義されています。
DismissAction構造体とは?
dismiss
プロパティにはDismissAction
構造体が格納されます。つまりdismiss
自体は単なるプロパティ名であり正体はDismissAction構造体ということになります。
DismissAction
構造体はインスタンスかされる際に暗黙的に自身が持つcallAsFunction
メソッドを呼び出し実行します。このメソッドが現在表示されているビューを閉じるメソッドになるようです。
使い方
dismissを使用する方法をみていきます。使用用途は「NavigationLinkで遷移したビューから戻る処理を実装」する際です。
使用する流れ
- 子供側に実装
- 環境変数dismissを使用可能にする
- アクション部分でdismiss()を実行
環境値を保持するEnvironmentValues
構造体の値は@Environment(\.プロパティ名)
で取得できます。
階層になっている場合のdismiss
ビュー構造が「親ビュー>子ビュー>子ビュー2」のように階層になっている場合でもdismiss
は正常に動作します。この場合はアクティブになっているビューのみが閉じられていきます。
孫Viewから親まで一気に戻る方法
孫Viewから親に一気に戻りたい場合は最適なメソッドはまだ用意されていなさそうでした。無理やり実装するならonDisappear
を使用して孫Viewが閉じられた時に子Viewも閉じることで親Viewまで一気に戻ることが可能です。しかしこの方法だと一瞬子ビューが見えてしまうので最適な方法とは言えなさそうです。
解決策
isDetailLink
を使用することで孫Viewから親まで一気に戻ることができるように実装できるみたいです。ロジックとしては親に@State
で変数を用意しておきその変数を@Binding
で孫まで繋いで、孫からその変数を操作する方法でした。この際に中間のナビゲーションページにはisDetailLink
を付与しないと動作しないようです。
おすすめ記事:Github-SwiftUIで初めの画面に遷移する
データを編集&dismissで戻るが実装できない?
先ほどの階層構造で問題なく動作したdismiss
処理ですが、思うように動作しないこともありました。作成していたのは「リスト画面→詳細画面→編集画面」へと遷移するページで、編集ボタンをクリック後に元データを編集後、詳細画面に戻る流れを期待して作成しています。

しかし上記のようなビュー構造の際に子ビュー2側で「更新(dismissを含んだ更新&戻る)ボタン」を実装した場合、子ビュー2でクリックすると親ビュー(リスト画面)まで戻ってしまいます。
デフォルトで実装される「戻るボタン」なら期待通りの遷移をしますが、dismiss
を使用したボタンの場合は期待通りに動きませんでした。以下にコードを載せておきます。
コードの概要
- [構造体]形式のデータをリスト表示
- @ObservedObjectと@EnvironmentObjectでデータを共有
- itemとして配列の要素を子ビューへ渡す
- 子ビュー2(編集ページ)でデータを編集後、更新&dismissで戻る
- 親ページに戻ってしまう?
アラートを使用することで解決
「編集ページ」から編集後に「詳細ページ」へ戻るためにアラートを使用することで解決できました。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。
私がSwift UI学習に使用した参考書
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。