🙌

capacitor/iosのkeyboardリサイズは自分でハンドリングするとスムーズになる話。

2020/12/24に公開

AndroidのWebViewはキーボードの出現により自動的にリサイズされる(※OSの機能としてリサイズされる)のですが、iOSは自動的にリサイズが行われません。ですので、LINEのような「Footer固定のInputフォーム」があると、自分でキーボードの高さだけリサイズする必要があります。

Capacitorはそのリサイズ機能として、 capacitor.config.jsonKeyboard > resize を指定することができます。

https://capacitorjs.jp/docs/apis/keyboard#keyboard-configuration-ios-only

しかし、実装的には キーボード出現後にリサイズが走る ようになっており、実際にリサイズされる様子をみると違和感を覚えることと思います。

Capacitorの機能(設定)でこれをスムーズにするための設定は現在のところありませんので、自分でスムーズにしてみましょう。

まず、Capacitorのリサイズ機能を切ります。 capacitor.config.json で無効にします。

...
  "plugins": {
    "Keyboard": {
      "resize": "none"
    }
  }

resize: none にします。ついで、キーボードを出現にあわせてスムーズにリサイズしたようにみせるためにアニメーションの設定をCSSで行います。Ionic/Angularの場合は ion-app ですが、ReactやVueプロジェクトではそれにあわせたセレクターを指定してください。

ion-app {
  margin-bottom: 0;
  transition: margin-bottom 420ms;
}

最後にキーボードの出現にあわせてWebViewを変化させます。最初のコンポーネント呼び出しの時点でリスナーを登録しておきましょう。

if (this.platform.is('ios')) {
    window.addEventListener('keyboardWillShow', (e) => {
      const app: HTMLElement = document.querySelector('ion-app');
      app.style.marginBottom = (e as any).keyboardHeight + 'px';
  });
  window.addEventListener('keyboardWillHide', (e) => {
    const app: HTMLElement = document.querySelector('ion-app');
    app.style.marginBottom = '0px';
  });
}

これで、キーボード出現時は、ViewのmarginBottomがキーボードの高さ分大きくなりますので、その変化に伴ってアニメーション(transition)が実行されるようになりました。
以下のような感じで挙動します。

https://twitter.com/rdlabo/status/1332656964166320129

簡単ですね。iOSのキーボード出現のアニメーション速度が一定ではないため、厳密にはtransitionでは少しずれてしまうので、こだわる方はもっと細かくアニメーションポイントを設定してください。つくったよ!という方は、以下のIssueで紹介してもらえると幸いです。

https://github.com/ionic-team/capacitor/issues/1540#issuecomment-735221275

それではまた。

Discussion