Closed stewones closed 1 month ago
Hi @stewones
The issue you're encountering is because the HTML content is moved on top of the keyboard (flickering).
This is not a issue of Ionic or Capacitor, but how the Webview is handling resizing.
You can manage the resizing on your own by changing capacitor.config.ts
const config: CapacitorConfig = {
...
Keyboard: {
resize: KeyboardResize.None,
},
...
},
};
https://capacitorjs.com/docs/apis/keyboard#configuration
You can also work with Ionic Keyboard Events to implement your own smooth keyboard transition like described in this blog.
You can read more about this issue here.
Hi @stewones
The issue you're encountering is because the HTML content is moved on top of the keyboard (flickering). This is not a issue of Ionic or Capacitor, but how the Webview is handling resizing. You can manage the resizing on your own by changing
capacitor.config.ts
const config: CapacitorConfig = { ... Keyboard: { resize: KeyboardResize.None, }, ... }, };
https://capacitorjs.com/docs/apis/keyboard#configuration
You can also work with Ionic Keyboard Events to implement your own smooth keyboard transition like described in this blog.
You can read more about this issue here.
I don't want to change the resize behavior, it doesn't work well for my use case.
yes I believe this is an issue with Capacitor and the webview. have you watched the video in full? see what happens in the end, the flash stops when I switch the OS theme to light.
That's true the other way around too. here's a video with the setting inverted (native background #000 and ionic light theme)
// capacitor.json
{
"backgroundColor": "#000000",
"ios": {
"backgroundColor": "#000000"
},
"android": {
"backgroundColor": "#000000"
}
}
https://github.com/ionic-team/capacitor/assets/719763/ee5e119d-d9d5-4df7-942d-2df5b45eda1c
As DwieDima said, this is really the WebView internals resizing, in the Capacitor Testapp I've set the background color to red to make it more evident and I see black flashes instead of red flashes. So adding this feature might fix the problem for you, but not for all users, will depend on the app internals.
The backgroundColor
was added for preventing a flash when changing from the splash screen to the WebView, that's why it's only considered to be set on the app startup and not programmatically, because in most cases the background color will not be seen again once the WebView appears.
The backgroundColor
configuration just sets the background color of the Webview on Android and the WebView and it's ScrollView on iOS, that's accessible from plugins code, so you could create a plugin that sets the background color from native side.
As DwieDima said, this is really the WebView internals resizing, in the Capacitor Testapp I've set the background color to red to make it more evident and I see black flashes instead of red flashes. So adding this feature might fix the problem for you, but not for all users, will depend on the app internals.
The
backgroundColor
was added for preventing a flash when changing from the splash screen to the WebView, that's why it's only considered to be set on the app startup and not programmatically, because in most cases the background color will not be seen again once the WebView appears.The
backgroundColor
configuration just sets the background color of the Webview on Android and the WebView and it's ScrollView on iOS, that's accessible from plugins code, so you could create a plugin that sets the background color from native side.
Thanks @jcesarmobile that makes sense. Yeah I recall having long conversations on Slack with you about the backgroundColor
capability, back in the Capacitor alpha/beta days.
While I disagree with you about the functionality only benefiting my use case, I agree that a plugin could make this happen and that was my plan since the beginning. I just thought that having it in the core would make more sense.
btw here's a video with the native background set as red as you mentioned. I barely see any black flash on both themes. so I still believe this could be a great addition.
https://github.com/ionic-team/capacitor/assets/719763/b3adb789-9017-4418-b62f-98ec8c52eea9
and this is why KeyboardResize.None
doesn't work for me. I doubt this is only my case.
https://github.com/ionic-team/capacitor/assets/719763/fddb9b1f-c73b-47c6-9d09-75b0ebb3d9ab
@stewones if you use Angular I can share a snippet where im also using KeyboardResize.None
and implemented my own css animation using a directive where the ion-footer
get animated on top of keyboard:
import { Directive, ElementRef } from '@angular/core';
import { Capacitor, PluginListenerHandle } from '@capacitor/core';
import { Keyboard, KeyboardResize } from '@capacitor/keyboard';
import { AnimationController } from '@ionic/angular';
@Directive({
selector: '[cdfyAnimateWithKeyboard]'
})
export class AnimateWithKeyboardDirective {
public keyboardWillShowListener?: PluginListenerHandle;
public keyboardWillHideListener?: PluginListenerHandle;
public resizeModeBackup?: KeyboardResize;
public keyBoardHeight = 0;
public isKeyboardVisible = false;
public isIos = Capacitor.getPlatform() === 'ios';
public animation = this.animationController
.create()
.addElement(this.elementRef.nativeElement)
.easing('cubic-bezier(0.17,0.54,0.42,0.79)')
.duration(250);
public constructor(
private elementRef: ElementRef<HTMLElement>,
private animationController: AnimationController
) {}
public async ngOnInit(): Promise<void> {
// Only handle keyboard events on ios
if (this.isIos) {
await this.handleKeyboardWillShow();
await this.handleKeyboardWillHide();
}
}
public async handleKeyboardWillShow(): Promise<void> {
this.resizeModeBackup = await Keyboard.getResizeMode().then(
(result) => result.mode
);
await Keyboard.setResizeMode({ mode: KeyboardResize.None });
this.keyboardWillShowListener = await Keyboard.addListener(
'keyboardWillShow',
({ keyboardHeight }) => {
this.keyBoardHeight = keyboardHeight;
this.animation.keyframes([
{ offset: 0, transform: 'translate3d(0, 0, 0)' },
{
offset: 1,
transform: `translate3d(0, -${this.keyBoardHeight}px, 0)`
}
]);
if (!this.isKeyboardVisible) {
this.animation.play().catch(() => {});
this.isKeyboardVisible = true;
}
}
);
}
public async handleKeyboardWillHide(): Promise<void> {
this.keyboardWillHideListener = await Keyboard.addListener(
'keyboardWillHide',
() => {
this.animation.keyframes([
{
offset: 0,
transform: `translate3d(0, -${this.keyBoardHeight}px, 0)`
},
{ offset: 1, transform: 'translate3d(0, 0, 0)' }
]);
if (this.isKeyboardVisible) {
this.animation.play().catch(() => {});
this.isKeyboardVisible = false;
}
}
);
}
public async ngOnDestroy(): Promise<void> {
const promises: Promise<void>[] = [];
if (this.resizeModeBackup) {
promises.push(Keyboard.setResizeMode({ mode: this.resizeModeBackup }));
}
if (this.keyboardWillShowListener) {
promises.push(this.keyboardWillShowListener.remove());
}
if (this.keyboardWillHideListener) {
promises.push(this.keyboardWillHideListener.remove());
}
await Promise.all(promises);
}
}
<ion-footer cdfyAnimateWithKeyboard>
<ion-toolbar color="light">
<ion-button
color="primary"
expand="block"
>
Fortfahren
</ion-button>
</ion-toolbar>
</ion-footer>
Using this approach, there is also no flicker. Here's the result:
https://github.com/ionic-team/capacitor/assets/26873275/2ea5e3a1-f0ce-451e-929b-aa1734d85b98
Hell yeah, that's even better. Thanks for sharing 👍
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out.
Description
there's a use case where changing the
backgroundColor
value in runtime would be awesome. Why? depending on the app theme (light/dark) and how you set those values incapacitor.config
, there's a little flash when closing the native keyboard. (see video demo below)Platforms
Request or proposed solution
Alternatives
none that I can think of. so today we can either please dark mode users or light mode users. not both.
Additional Information
see the flash with native background set to #FFF and ionic dark theme. being able to change the native background in runtime would make hybrid apps' UX magnificence.
https://github.com/ionic-team/capacitor/assets/719763/a0114755-27f9-4ac7-8d85-302cc63226ac