本文へ移動
WebView Native UIdocs

Ionicオーバーレイ

IonicモーダルなどのWebオーバーレイをEngine管理下のネイティブコンテンツより上に表示する場合に、このアダプターを使います。ネイティブ登録はキャプチャと復元を処理しますが、ネイティブビューからIonicの表示ライフサイクルを推定することはできません。この共有モニターが、すべての登録に対して被覆を判定します。

アプリでは、Engine対応プラグインと組み合わせてこのアダプターを使います。プラグインの作者は、まずCapacitorまたはCordovaのガイドに従って組み込みます。Ionic以外のアプリは独自のライフサイクル通知を使い、このアダプターを導入しません。

/ionicエントリーポイントは共通のフレームワーク連携を提供します。Ionicのオーバーレイを監視し、登録されたどのサーフェスを覆うかを判定します。プラグインの明示的な表示制御は、そのプラグインのAPIの一部として維持し、投影通知または既存のレンダラーAPIを通じて接続します。

たとえば、Ionicの設定モーダルを開くと、背景のネイティブタブバーは覆いながら、モーダル自身のネイティブの閉じるボタンは操作可能に保つ必要があります。一律の非表示通知では、この関係を表せません。共有モニターはオーバーレイの積み重なりに対して各ホストを評価するため、独立したプラグインでも同じ被覆ルールを使えます。

一度だけ有効化する

Ionicアプリケーションでは、アプリの起動時に一度だけ呼び出します。アプリから直接呼び出す場合は、@webview-native-ui/engineをアプリの直接依存としてインストールしてください。

import { enableSupportIonicOverlays } from '@webview-native-ui/engine/ionic';

enableSupportIonicOverlays();

プラグインのメンテナーは、アプリのセットアップ手順にこのコードを記載するか、既存のJS初期化関数内で呼び出せます。@rdlabo/capacitor-native-uiは内部で同じ初期化関数を呼び出しているため、その利用者による追加の呼び出しは不要です。Ionic以外のアプリでは省略します。ネイティブ登録だけではIonicイベントのリスナーは追加されません。

被覆とライフタイム

npmモジュールとSwift/Androidから注入されたランタイムの間でも、ドキュメントごとに1つのモニターを共有します。繰り返し初期化してもリスナーは増えず、明示した設定も消えません。1つの投影を破棄しても、その購読だけを解除し、他のプラグインが使うモニターは停止しません。モニターはドキュメントとともに存続します。

デフォルトではModal、Popover、Alert、Action Sheet、Loading、Picker、Toast、Menuのライフサイクルイベントを扱います。各投影のDOMと有効なオーバーレイスタックを比較し、最前面のモーダル内のコンテンツはネイティブのまま、覆われたコンテンツは一時的に準備済み画像を使います。Toastや有効でないシートの背景は、サーフェスを覆いません。オーバーレイが入れ子の場合、残りのスタックが復元を許可するまで被覆を維持します。画像がなければ通常のWebフォールバックを保ちます。この一時的な被覆で、プラグインが明示したwebやnoneの投影先を上書きすることはありません。後から登録された投影も現在の状態を読み取ります。

ここでいうAlertは、Ionicのion-alertです。このアダプターはwindow.alert()を横取りせず、HTMLの<dialog>を自動検出したり、ネイティブダイアログを監視したりしません。カスタムWebオーバーレイは、後述のadditionalを通じてライフサイクルイベントを提供できます。

ネイティブウィンドウに表示されるPopoverは、WebView内に描画されるPopoverとは異なります。そのDOMプレースホルダーを、上を覆うWebオーバーレイとして扱ってはいけません。@rdlabo/capacitor-native-uiプラグインは、このネイティブ表示の所有権をモニターへ通知します。ネイティブ表示に失敗すると所有権を解放し、モニターは通常のWebオーバーレイの被覆判定を再開します。この例外には明示的な連携が必要であり、PopoverのDOMだけから推定するものではありません。

特殊なレイアウトのカスタマイズ

任意の設定はドキュメント全体に適用されます。通常のIonicオーバーレイではデフォルトを維持してください。 同じ/ionicエントリーポイントからエクスポートされるIonicOverlayOptionsは、これらの設定のTypeScript型です。別の初期化関数ではありません。ネイティブコンテンツを覆うべきでないアプリのオーバーレイにはexcludeを、同じアプリが独自のライフサイクルイベントを持つカスタムダイアログも使う場合にはadditionalを指定します。DOMの包含関係と背景の状態だけでは、その特殊なレイアウトが実際に覆うホストを表せない場合にのみcoversを使います。

enableSupportIonicOverlays({
  exclude: '[data-nonblocking-overlay]',
  additional: [
    {
      selector: 'app-dialog',
      events: {
        willPresent: 'appDialogWillPresent',
        didDismiss: 'appDialogDidDismiss',
      },
    },
  ],
});

登録済みDOM投影に独自の被覆ルールが必要な場合にのみ、covers(overlay, target)を使います。デフォルトに従う場合はundefined、上書きする場合は真偽値を返します。除外指定と明示的なネイティブウィンドウの所有権が優先されます。標準の関係は、任意のCSSスタッキングコンテキストを解釈するのではなく、オーバーレイの順序、DOMの包含関係、背景の状態を使います。特殊なレイアウトは明示的に設定してください。

プラグインがモーダルの背後にあるモーダルを知る必要がある場合

通常のアプリ設定では、上の例のようにenableSupportIonicOverlays()を使います。これにより、追加の呼び出しなしでEngineがIonicオーバーレイの被覆を処理します。

Ionicモーダル内にネイティブコントロールを配置するプラグインでは、開こうとしているモーダルの背後にどのモーダルがあるかも必要になる場合があります。同じ/ionicエントリーポイントの2つのヘルパーを使うと、Engineがすでに追跡しているモーダルの順序を読み取れます。

たとえば、モーダルAを開き、その上にモーダルBを開くとします。

  • ionicModalStack(document)は、背面から前面への順で[A, B]を返します。
  • coveredIonicSurface(B)は、Bの下のモーダルであるAを返します。
  • Bの上にPopoverを開くと、coveredIonicSurface(popover)はBを返します。
  • coveredIonicSurface(A)はundefinedを返します。Aの背後のページはモーダルではないためです。

ここでAとBは実際のion-modal DOM要素です。これらのヘルパーは追跡済みのモーダルの順序を読み取るだけで、オーバーレイの開閉、投影の切り替え、監視の開始は行いません。enableSupportIonicOverlays()で監視を有効にし、対象のオーバーレイが表示ライフサイクルに入った後に呼び出してください。