これまで何度かNavigationServiceについて取り扱った記事を書いてきました。
特に以下のエントリーでは、INavigationAwareとIConfirmNavigationについて記載しました。
しかしコメント欄でも話題になっているように、現時点では幾つか期待した振る舞いにならない問題があります。
なお、この問題はPrismのと言うよりは、Xamarin.Forms側の実装待ちな側面が強いようです。
フレームワークとして、本来不要な一時対応を行わないというスタンスは正しいのでしょうけれど、アプリケーションを開発する側としては回避策が必要でしょうし、対応方法を整理してみました。
なお本エントリーは連載記事「Prism for Xamarin.Forms入門」の一部となっております。
以下に目次がありますので、他のエントリーもご覧いただけると嬉しいです。
【Xamarin】Prism.Forms入門 目次 - nuits.jp blog
というわけで、さっそく本題に入りましょう。
問題
発生条件
- Android・Win10Mの戻るボタンで前画面へ戻った場合
- NavigationPageのNavigationBarの戻るボタンで前画面へ戻った場合
現象
- INavigationAware・IConfirmNavigationのOnNavigatedToやOnNavigatedFromが呼び出されない
- IConfirmNavigationでCanNavigateが呼び出されず、画面遷移の抑制が効かない
対策方法
ひとまず、IConfirmNavigationのCanNavigateは忘れます。。。
INavigationAwareのOnNavigatedToとOnNavigatedFromを代替する方法を検討します。
私の知る範囲で、手軽そうな対処方法は2種類あります。
- PageクラスのAppearing・Disappearingメソッドをハンドルする
- NavigationPageクラスのPush・Pop関連イベントをハンドルする
ただし、いずれの場合も引数の受け渡しについては考慮しないものとします。
問題が発生するのは戻る場合だけのため、利用頻度が低いシナリオのために対応方法を複雑化するのは避けることにしました。
どうしても必要であれば、画面間で共有されているModelで状態を保持するなど、別途個別に対応を検討してください。
PageクラスのAppearing・Disappearingメソッドをハンドルする
代替するとした場合、振る舞い的に近いのはこちらになるでしょう。
もう一方と比較した場合の欠点は、ViewとViewModel双方に個別に対応が必要となる点です。
とは言っても、大きな労力ではないため、特別な理由がない限りこちらを利用することをお勧めします。
具体的な実装については、別途以下のエントリーに記載しましたのでそちらをご覧ください。
NavigationPageクラスのPush・Pop関連イベントをハンドルする
こちら方式は、個別のViewへの対応は不要ですが、挙動がINavigationAwareと異なります。
A画面からB画面へ戻る際に、A画面を離脱する際のOnNavigatedFromに対する振る舞いは対応できますが、B画面を表示する際のOnNavigatedToに対応することができません。
ただし、実装自体はやや簡便になりますので、前述の方法とケースによって使い分けて頂けたらと思います。
というわけで、今回は以上です。
それではまた!