I was just comparing ChatGPT to my app on keyboard focus and it’s pretty rough. Any way to fix? I am using Ionic/Vue. @ldebeasi I feel like this is something you might know about?
ChatGPT:

My app:

I was just comparing ChatGPT to my app on keyboard focus and it’s pretty rough. Any way to fix? I am using Ionic/Vue. @ldebeasi I feel like this is something you might know about?
ChatGPT:

My app:

Smooth keyboard transitions are hard to do because the input is in the web layer but the keyboard is in the native layer. As a result, the animations will never be perfectly in sync. However, there are a couple things you can do to get pretty close:
Use something other than the “Native” resize Keyboard behavior: Keyboard Capacitor Plugin API | Capacitor Documentation This causes the entire webview to resize which is likely causing the noticeable jump in your demo. Using other values will prevent the entire webview from resizing. You may need to try all the options as I’m not sure where the input is in the DOM in your demo. You may end up just wanting to use the “None” option.
Use a keyboardWillShow listener to detect when the keyboard is about to open and translate the input by the keyboard height. The event payload gives you the height of the keyboard. You can then apply a translateY transform with a transition to smoothly animate the input above the keyboard. Don’t forget to also listen for keyboardWillHide to remove the transform.
I wrote a blog using the Ionic Keyboard Events that has similar code you can use: Keyboard improvements for Ionic Apps - Ionic Blog
Makes sense what you’re saying Liam. Is it possible for you to post the example you use in the article? You are doing exactly what I am trying to accomplish. I am building a chat bot app so it looks very smooth what you did but I don’t see any code example. Lmk if that’s available!
Sadly I don’t have the source code for that anymore, but the code snippets show generally what you’ll need to do for the input. The code was written in vanilla JS, but it should be adaptable to whatever framework you are using.
This should be prioritised by Ionic team, the Native Resize mode should transition with an animation the web view height being reduced instead of instantly setting it to the new height
Fully agree with that, that’s an UI problem hybrid have since a long time, would be very amazing to get this animation more “native” and not managed with heavy javascript calculation / animation
<ion-content ref="contentRef" :style="{ '--padding-bottom': (keyboardHeight || 30) + 'px' }"> (....)
<ion-footer :class="{ 'fade-out-in': fadeKeyboardOut }" :style="isIos ? { transform: `translateY(-${keyboardHeight}px)` } : {}">
<ion-toolbar>
<chatbox
@focused="fadeKeyboardOut = true"
/>
</ion-toolbar>
</ion-footer>
so the idea here is to cater to different behaviours on ios and adroid. Android works by itself if u just set Keyboard resize to body but it’s jumpy - so we animate that, hide the footer and fade-in when keyboard is open
with iOS we need to set listeners and a nice transition css, there we can actually quite easily achieve that nice “push up” look that native swift can get u .. but we have to set Keyboard resize to none and therefore also add the keyboardHeight property to act as --padding-bottom for ion-content because with resize on None our content would go behind the keyboard.
so .. keyboardHeight is iOS and fadeKeyboardOut is for android.
IOS
To set keyboardHeight is enough to do it in the keyboardWillShow listener cause we do want it to “travel” with the keyboard. So we just do this.
addKeyboardListeners() {
if (this.isIos) {
Keyboard.addListener("keyboardWillShow", ({ keyboardHeight }) => {
this.keyboardHeight = keyboardHeight
})
Keyboard.addListener("keyboardWillHide", () => {
this.keyboardHeight = 0
})
}
Keyboard.addListener("keyboardDidShow", () => {
this.scrollToBottom()
})
},
and css (very important)
ion-footer {
transition: transform 290ms cubic-bezier(0.17, 0.54, 0.42, 0.79);
}
we insert the variable in ion-footer and ion-content as shown above in the first code block.
ANDROID
For android, u need to emit out the @ion-focus event from you ion-textarea or ion-input cause that event runs before keyboardWillShow and we need to fight even ms to avoid the nasty jumps. As seen in my footer I then straight on the emit set the fadeKeyboardOut to true .. → @focused="fadeKeyboardOut = true" that toggles the animation on, on ion-footer we have this :class="{ 'fade-out-in': fadeKeyboardOut }" which triggers after toggling this animation
.fade-out-in {
animation: fade-out-in 290ms linear;
}
@keyframes fade-out-in {
0% { opacity: 0; }
50% { opacity: 0; }
100% { opacity: 1; }
}
we basically just want to make it disappear straight away, since the keyboard starts going up it’s unnoticeable anyway, the goals is to especially make it fade-in nicely when it’s all settled
FOR BOTH
Last but not least, u can set some fallback in your capacitor.config.ts but u need to add a dynamic resize toggle to main.js
Keyboard: {
resize: 'body',
},
in main.js
// creates global variable with app version
await setAppVersion()
// resize on iOS has to be on none and manually setting bottom for footer to achieve smooth transition, android is automatic (and jumpy)
Keyboard.setResizeMode({ mode: window.PLATFORM === "ios" ? "none" : "body" })
It may seem like a lot but that’s just cause I explained every detail, it’s actually pretty straight forward and before they figure out some proper way this is a decent workaround.
There is still a little random flicker on android, but still better than what it usually is