Ionic/Angularでハーフモーダルを実装する
この記事はIonic Framework / Capacitor Advent Calendar 2020の記事です。
iOSで時々見かけていた「ハーフモーダル」ですが、最近ではAirPodsの確認画面であったり、購入確認のUIであったりよく見かけるようになりました。
※ スクリーンキャプチャ攝る時に指紋認識してジェムパックAを購入してしまったのは笑い話
元々モーダルはPUSH遷移と異なり、以前のビューと非連続的な処理をする時に利用するものですが、全面のモーダルは以前のビューが見えなくなることに対して、ハーフモーダルは以前のビューが「見えてる状態での作業の中断」を明示することができます。それでは、これをIonic/Angularで実装してみましょう。
一番シンプルなハーフモーダル
まず、 half-modal
のためのCSSを用意します。 global.scss
などグローバルに適用されるSCSSに記述してください。
.half-modal {
align-items: flex-end;
.modal-wrapper {
height: 400px !important;
}
ion-header ion-toolbar:first-of-type {
padding-top: 0;
}
}
ion-app
は display: flex
ですので、その直下に入るハーフモーダルは align-items: flex-end;
で下寄せを指定します。そして、 wrapper
に400pxを用意します。 ion-header ion-toolbar:first-of-type
を指定しているのは、Cordova/Capacitorで利用してる時に、iOSでは自動的に ion-header ion-toolbar
の padding-top
が変更されるのを防ぐためです。
これで、Modalを立ち上げる時にこのClassを割り当てればOKです。ハーフモーダルはスワイプでも閉じれた方がいいので、 swipeToClose
も有効にします。
const modal = await this.modalCtrl.create({
component: ModalPage,
cssClass: ['half-modal'],
swipeToClose: true,
});
await modal.present();
簡単ですね。
全面モーダルの上にハーフモーダルをだす
ただ、往々にしてハーフモーダルは全面モーダルの上に表示します。全モーダルを重ねて作業を中断させないためであり、ユーザに多くのビューを提示して混乱させないための配慮でもあります。ただ、上記のハーフモーダルの出現方法だと、ハーフモーダルの背景にバックドロップが表示されない問題があります。
これはIonicではModalは2枚以上だした場合、1枚目の上にくるために半透明のバックドロップが複数重なって(opacityが重なって)画面が黒くなることを防止しているためです。
ハーフモーダルでは2枚目であってもバックドロップを表示するようにCSSで指定します。
.half-modal {
align-items: flex-end;
.modal-wrapper {
height: 400px !important;
}
ion-header ion-toolbar:first-of-type {
padding-top: 0;
}
+ ion-backdrop {
+ --backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
+ }
}
そうすると、ハーフモーダルの後ろにもバックドロップが表示されます。便利ですね。
キーボード出現時にハーフモーダルを全面モーダルにする
モバイルデバイスでは、キーボード出現時はキーボードで画面が1/3近くを占めてしまうため、ハーフモーダルは邪魔です。もちろん、キーボードとハーフモーダルを組み合わせないUI設計をすればいいのですが、設計上組み合わせるのが必要な場合はキーボードと一緒にせり上がるようにしましょう。
まず、 .half-modal
が高さが変わったらアニメーションで変化を表示するようにします。そしてModalの高さを一時的に100%にして、 ion-header ion-toolbar
の padding-top
も初期値に戻しましょう。
.half-modal {
align-items: flex-end;
.modal-wrapper {
+ transition: height 420ms;
height: 400px !important;
}
ion-header ion-toolbar:first-of-type {
padding-top: 0;
}
ion-backdrop {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
}
+ &.half-modal-keyboard {
+ .modal-wrapper {
+ height: 100% !important;
+ }
+
+ ion-header ion-toolbar:first-of-type {
+ padding-top: var(--ion-safe-area-top, 0);
+ }
}
}
これでキーボード出現時には、 .half-modal-keyboard
を付与、キーボードが閉じる時には .half-modal-keyboard
を削除すれば、キーボードにあわせて、ハーフモーダルと全面モーダルを切り替えることができるようになります。
こんな感じになります。
簡単ですね。それではまた。
Discussion