nuits.jp blog

C#, Xamarin, WPFを中心に書いています。Microsoft MVP for Visual Studio and Development Technologies。なお掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Prism 6.3の変更点 その2 画面遷移関連(for Xamarin.Forms)

Prism 6.3のXamarin.Forms向けで最も大きな変更があったのが画面遷移関連です。
機能追加もありますし、注意が必要な破壊的変更もあります。

【破壊的変更】INavigationAwareのAPI変更

破壊的変更とはいえ、これはあまり大きな影響はありません。
INavigationAware関連には、おもに次の3種類の変更が加えられました。

  • INavigatingAwareインターフェースの新規追加
    • 新たにOnNavigatingToメソッドの追加
  • INavigatedAwareインターフェースの新規追加
    • INavigationAwareに存在した次の二つのメソッドをこちらへ移動
      • OnNavigatedFrom
      • OnNavigatedTo
  • 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が実装していた多くのメソッドが利用できなくなっていますので、詳しくはコードを見てみる方が良いでしょう。

https://github.com/PrismLibrary/Prism/blob/master/Source/Xamarin/Prism.Forms/Navigation/NavigationParameters.cs

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のアップデートで挙動が変わることが多かったため、注意してください。

以上です。