Prism 6.3のXamarin.Forms向けで最も大きな変更があったのが画面遷移関連です。
機能追加もありますし、注意が必要な破壊的変更もあります。
- 【破壊的変更】INavigationAwareのAPI変更
- 【破壊的変更】IConfirmNavigation、IConfirmNavigationAsyncのAPI変更
- 【破壊的変更】NavigationParametersのAPIの変更と、配列のサポート
- 物理バックキー及びNavigationBarの戻るボタン選択時のイベントハンドリングの実装
- IDestructibleインターフェースの追加
- TabbedPageのタブ変更通知の実装
【破壊的変更】INavigationAwareのAPI変更
破壊的変更とはいえ、これはあまり大きな影響はありません。
INavigationAware関連には、おもに次の3種類の変更が加えられました。
- INavigatingAwareインターフェースの新規追加
- 新たにOnNavigatingToメソッドの追加
- INavigatedAwareインターフェースの新規追加
- INavigationAwareに存在した次の二つのメソッドをこちらへ移動
- OnNavigatedFrom
- OnNavigatedTo
- INavigationAwareに存在した次の二つのメソッドをこちらへ移動
- INavigationAwareが上記二つのインターフェースを継承するように変更
したがって、従来INavigationAwareを実装していたViewModelなどで、特別な変更は不要です。
INavigationAwareに対して、Refractionなどを利用していない限りあまり影響はないと思われますし、そういう人も殆ど存在しないのではないでしょうか?
さて、新たにINavigatingAwareインターフェースが追加されOnNavigatingToメソッドが追加された点は、利便性に対して大きなメリットとなっています。
これまでOnNavigatedToでは、画面遷移した後、次の画面が表示された後にイベントが通知されていましたが、OnNavigatingToメソッドでは遷移前に通知されます。
画面の初期化処理はこちらで実装すると、良いケースが多いでしょう。
ただし次の点に注意してください。
「NavigationPageのNavigationBarや物理バックキーで戻った時は呼び出されないが、INavigationService#GoBackAsyncで戻った時には呼び出される」
このため、次の画面に遷移するときにリソースを開放しておいて、戻ってきたときに再度リソースを取得し直す、といった処理はOnNavigatingToには向きません。
また、INavigationService#GoBackAsyncで戻ってきたときにも呼び出されますので、「続けて何度呼ばれても正しく動作する」ように冪等性を確保する必要があります。(たぶん
【破壊的変更】IConfirmNavigation、IConfirmNavigationAsyncのAPI変更
これは大きな影響のある破壊的変更であり注意が必要です。
これまでIConfirm~の二つのインターフェースは、いずれもINavigationAwareを継承していましたが、6.3から継承が削除されました。
したがって次の条件をすべて満たした場合、これまで呼び出されていたOnNavigatedFromとOnNavigatedToが呼び出されなくなります。
- OnNavigatedFromやOnNavigatedToを利用している
- IConfirmNavigationもしくはIConfirmNavigationAsyncを実装している
- INavigationAwareを実装していない
IConfirm~を実装していて、INavigationAwareを実装していなかったViewModelなどでは、新たにINavigationAwareを明示的に実装する宣言が必要となります。
【破壊的変更】NavigationParametersのAPIの変更と、配列のサポート
6.2までNavigationParametersは Dictionary<string, object>を継承していましたが、IEnumerable<KeyValuePair<string, object>>を実装するように修正されました。
これに伴って、これまでParameterの設定は次のように実施できましたが
var params = new NavigationParameters(); params["key"] = value;
6.3以降は次のように記載する必要があります。
var params = new NavigationParameters(); params.Add("key", value);
また当然Dictionaryが実装していた多くのメソッドが利用できなくなっていますので、詳しくはコードを見てみる方が良いでしょう。
Dictionaryとしての機能は大きく失われましたが、URL表記を利用した場合に、ダイレクトに配列がサポートされるようになりました。
たとえば次のように記載した場合
navigationService.NavigateAsync("somePage?car=Ford&car=Dodge&C=car=chevy");
carの値を配列として使用できます。
これは主にDeepLinkを想定した仕様変更でしょう。
物理バックキー及びNavigationBarの戻るボタン選択時のイベントハンドリングの実装
6.2までは物理バックボタンやNavigationBarの戻るボタンを押下された際に、OnNavigatedFromやOnNavigatedToが呼び出されませんでした。
6.3からはこれらの通知が有効となるようになりました。
ただし、先にも書いた通りOnNavigatingToには対応していませんので注意してください。
これはXamarin.FormsのNavigationPageのイベントがOnPoppedは存在するが、OnPoppingが存在しないことが要因であり、しばらくは対処されることはないと思われます。
IDestructibleインターフェースの追加
Pageが何らかの戻る処理で不要となった場合に(つまりStackからポップされた場合)、IDestructibleのOnDestoryを実装することでイベントを受信できるようになりました。
イベントハンドラやRx系のSubscribeの解除などに利用すると、リソースリークを簡単に防ぐことが可能となりました。
非常に便利ですね。
TabbedPageのタブ変更通知の実装
これは厳密にいうと「画面遷移(Navigation)」ではないのですが。。。
TabbedPageの子の個々のタブに該当するPage、もしくはそのViewModelでIActiveAwareを実装することで、タブの選択変更イベントがハンドルできるようになりました。
変更通知は次のいずれかの場合に行われます。
- 選択されたTabが変更された場合
- Root画面のAppearing、Disappearingが呼ばれた場合
特に後者はプラットフォームによって挙動がやや異なる点と、これまでのXamarin.Formsのアップデートで挙動が変わることが多かったため、注意してください。
以上です。