Ionic 4 keyboard covers input field

感情迁移 提交于 2020-01-24 04:23:07

问题


I have an Ionic 4 app that has a form with inputs in it.
When the user clicks on the input, it opens the keyboard, but it hides the content, without scrolling.
Is there any way around this?

This is my code:

<form #f="ngForm" (ngSubmit)="sendMail()">
   <ion-item>
     <ion-label position="floating">name
     </ion-label>
     <ion-input [(ngModel)]="senderName">
     </ion-input>
   </ion-item>

   <ion-item>
      <ion-label position="floating">mail
      </ion-label>
      <ion-input [(ngModel)]="senderMail">
      </ion-input>
    </ion-item>

    <ion-item class="borderedTextArea">
      <ion-textarea [(ngModel)]="mailText" style="height:150px;"></ion-textarea>
    </ion-item>

    <ion-button type="submit" style="float:left">send</ion-button>

</form>

回答1:


I'm currently using Ionic4 with Cordova 9 and all the latest packages, and I could not find any settings within the framework that worked for me. In the end I made this workaround that completely circumvents the framework. It has a little animation and looks pretty OK, so I'm using it until the framework solves this properly.

global.scss

ion-app {
    /*animation of native keyboard show*/
    transition: margin 300ms;
}

app.component.ts

declare var $: any;

ngAfterViewInit() {
    // This element never changes.
    let ionapp = document.getElementsByTagName("ion-app")[0];

    window.addEventListener('keyboardDidShow', async (event) => {
        // Move ion-app up, to give room for keyboard
        let kbHeight: number = event["keyboardHeight"];
        let viewportHeight: number = $(window).height();
        let inputFieldOffsetFromBottomViewPort: number = viewportHeight - $(':focus')[0].getBoundingClientRect().bottom;
        let inputScrollPixels = kbHeight - inputFieldOffsetFromBottomViewPort;

        // Set margin to give space for native keyboard.
        ionapp.style["margin-bottom"] = kbHeight.toString() + "px";

        // But this diminishes ion-content and may hide the input field...
        if (inputScrollPixels > 0) {
            // ...so, get the ionScroll element from ion-content and scroll correspondingly
            // The current ion-content element is always the last. If there are tabs or other hidden ion-content elements, they will go above.
            let ionScroll = await $("ion-content").last()[0].getScrollElement();
            setTimeout(() => {
                $(ionScroll).animate({
                    scrollTop: ionScroll.scrollTop + inputScrollPixels
                }, 300);
            }, 300); // Matches scroll animation from css.
        }
    });
    window.addEventListener('keyboardDidHide', () => {
        // Move ion-app down again
        // Scroll not necessary.
        ionapp.style["margin-bottom"] = "0px";
    });
}



回答2:


I've solved this Ionic bug provisionally with:

...
<ion-texarea (ionFocus)="fixTextareaBug()">
...

and in your .ts

@ViewChild(IonTextarea)
public ionTextArea: IonTextarea;
private focusFix = false;

...
...

public fixTextareaBug() {
  setTimeout(() => {
    if (this.focusFix) {
      this.focusFix = false;
      return;
    }
    (this.ionTextArea as any).el.lastElementChild.blur();
    this.focusFix = true;
    (this.ionTextArea as any).el.lastElementChild.focus();
  }, TEXTAREA_TIMEOUT);
}

I hope it solved your problem




回答3:


I solve that by downgrading the keyboard plugin

ionic cordova plugin remove cordova-plugin-ionic-keyboard

ionic cordova plugin add cordova-plugin-ionic-keyboard@2.0.5

and then remove the android platform and add it again




回答4:


I was having that issue too but only in android, what i did was to create a script that get the height of the focused element and the keyboard, and using jQuery I added a marginTop to move the body above the keyboard when the keyboard shows, this is my code:

constructor(
    private platform: Platform,
    private keyboard: Keyboard
  ) {
    if(this.platform.is('android')){
      this.keyboard.onKeyboardShow().subscribe((e) => {
        const offset = $(document.activeElement).offset().top;
        let height = (offset - e.keyboardHeight)*-1;
        height = height > 0 ? 0 : height;      
        $('body').animate({ 'marginTop': height + 'px' }, 100);
      });
      this.keyboard.onKeyboardHide().subscribe(e => {
        $('body').animate({ 'marginTop': 0 + 'px' }, 100);
      });
    }
}

libs needed:

    npm install jquery
    npm install @types/jquery
    ionic cordova plugin add cordova-plugin-ionic-keyboard
    npm install @ionic-native/keyboard

imports

    import { Platform } from '@ionic/angular';
    import * as $ from "jquery";
    import { Keyboard } from '@ionic-native/keyboard/ngx';

Is not an elegant solution but it works

Just some change in this code will give better experience

this.keyboard.onKeyboardShow().subscribe((e) => {
    const safeArea = 40 ;
    const offset1 = $(document.activeElement).offset().top;
    const offset2 = window.innerHeight - e.keyboardHeight - $(document.activeElement).height() - safeArea ;
    const diff = offset1 - offset2;
    if(offset1 > window.innerHeight -  e.keyboardHeight - safeArea)
        $('body').animate({ 'marginTop': -1 * diff + 'px' }, 100);
});

enter image description here



来源:https://stackoverflow.com/questions/54647893/ionic-4-keyboard-covers-input-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!