cordova 如何修复键盘覆盖Windows上的输入字段(表面)

jhkqcmku  于 2022-11-15  发布在  Windows
关注(0)|答案(2)|浏览(222)

我有一个离子4 /角 cordova 为基础的应用程序(离子信息结束后)。
我目前正在使用 cordova Windows 6. 0. 1由于this issue。所有似乎工作正常,除了这个什么这个问题是关于。
当我在Windows Surface平板电脑上选择一个输入字段时,键盘覆盖了输入字段,即应用程序不会像在iOSAndroid上那样降低它的高度(它在其他两个平台上工作得很好)。
当我查看正在工作的Android设备上发生的情况(使用chrome://inspect)时,我注意到带有选择器ion-appmd ion-page hydrated的元素的高度从616p x减少到325px
我还没有找到一种方法来做同样的调试远程Windows设备,所以我不能调查这一点,但我认为上述只是没有发生。
我发现了this post,这对我来说很有意义,因为它看起来是在调整ion-app的高度。我复制了这段代码(去掉了jQuery),但我的问题是,当我在表面上调用键盘时,keyboardDidShow事件似乎没有触发(我将日志发送到服务器,所以我可以看到这没有发生)。
所以我的(类似的)代码如下:

const ionApp = document.getElementsByTagName("ion-app")[0];
  this.logger.info(ionApp ? "got app" : "not got app");
  
  window.addEventListener('keyboardDidShow', async (event) => {        
    this.logger.info('keyboardDidShow'); // <----- don't even get to here
    
    // Move ion-app up, to give room for keyboard
    let kbHeight: number = event["keyboardHeight"];
    let viewportHeight: number = window.innerHeight;

    this.logger.info(`viewportHeight: ${viewportHeight}`);

    const focusedElement = document.activeElement;
    if (!focusedElement) {
      this.logger.warn('windowsKeyboardWorkaround: Could not get focused input');
      return;
    }

    let inputFieldOffsetFromBottomViewPort: number = viewportHeight - focusedElement.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) {
      const content = document.getElementsByTagName('ion-content');
      if (!content || content.length == 0)
        return;
      
      const topMostContent = content[content.length - 1];
      let ionScroll = await topMostContent.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";
  });

为什么我没有触发此事件,或者是否有方法查看window(或其他)上的所有事件,以查看是否引发了键盘事件?

更新1

我在Android上运行时忘记删除这段代码,我注意到keyboardDidShow * 在这里被提升了(即在Android上,我当然不需要它)。所以它看起来只是在Windows上,或者至少是我必须测试的Surface平板电脑上。

更新2

keyboardDidHide事件看起来像是来自Cordova keyboard plugin,这里是说只支持iOS和Android。果然,如果我们转到source,我只看到iOS和Android:

所以我需要一些其他的方法。

更新3

在我的应用程序中的其他地方,我使用以下命令隐藏Windows后退按钮:

let w: any = window;
 if (w.cordova != undefined && w.cordova.platformId == "windows") {
    let currentView = w.Windows.UI.Core.SystemNavigationManager.getForCurrentView();
    currentView.appViewBackButtonVisibility = w.Windows.UI.Core.AppViewBackButtonVisibility.collapsed;
  }

这意味着我们可以访问Windows.UI.Core,我假设所有内容都在this namespace中。
到目前为止,我看不到任何可以连接到键盘的显示/隐藏功能。
Windows-universal-samples\Samples\TouchKeyboard\cs下的hereUWP示例中,我在Scenario2_ShowHideEvents.xaml.cs中看到以下内容...

protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        InputPane currentInputPane = InputPane.GetForCurrentView();

        // Subscribe to Showing/Hiding events
        currentInputPane.Showing += OnShowing;
        currentInputPane.Hiding += OnHiding;
    }

但不确定从哪里得到这个从Windows.UI.Core
离子信息

Ionic:

       Ionic CLI                     : 5.2.3 (C:\Users\peter\AppData\Roaming\npm\node_modules\ionic)
       Ionic Framework               : @ionic/angular 4.11.3
       @angular-devkit/build-angular : 0.802.0
       @angular-devkit/schematics    : 8.2.0
       @angular/cli                  : 8.2.0
       @ionic/angular-toolkit        : 2.0.0

    Cordova:

       Cordova CLI       : 9.0.0 (cordova-lib@9.0.1)
       Cordova Platforms : android 8.1.0, windows 6.0.1
       Cordova Plugins   : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 4.1.3, (and 12 other plugins)

    Utility:

       cordova-res : 0.7.0-testing.0
       native-run  : 0.2.8

    System:

       Android SDK Tools : 26.1.1 (C:\Users\peter\AppData\Local\Android\sdk)
       NodeJS            : v10.15.3 (C:\Program Files\nodejs\node.exe)
       npm               : 6.4.1
       OS                : Windows 10
p8h8hvxi

p8h8hvxi1#

我也是刚从这种情况中走出来。
在app.component.ts中-在平台准备就绪后尝试添加此

this.statusBar.overlaysWebView(false)
this.statusBar.styleDefault();
a0x5cqrl

a0x5cqrl2#

我想出了一个解决方案,虽然不是100%完美,因为它没有得到确切的键盘高度。我只是把视口分成两半,但它是不是比什么都没有好。
我将粘贴我的整个类(这两个util助手将很容易计算出它们的作用)

import { Injectable } from '@angular/core';
    import { Utils } from '@shared/utils';
    import { Logger } from './logger.service';

    /**
     * Manages the Windows soft keyboard showing / hiding and resizing the app when it is shown/hidden
     */
    @Injectable()
    export class WindowsKeyboardService {
        /**
         * Construction
         * @param logger - logger
         */
        constructor(private logger: Logger) { }

        /**
         * Call from main component once the view is visible, so we can get access to Windows Input pane
         * and hook up the soft keyboard handlers
         */
        public async hookupKeyboardHandlers() : Promise<void> {
            try {
                this.logger.info('hookupKeyboardHandlers');

                // Only need this for Windows. For ioS/Android the keyboard plugin does all this for us.
                if (!await Utils.isWindows()) {
                    this.logger.info('WindowsKeyboardService.hookupKeyboardHandlers - not windows. Skipping');
                    return;
                }
                
                let w = <any>window;
                const inputPane = w.Windows.UI.ViewManagement.InputPane.getForCurrentView();
                if (!inputPane) {
                    this.logger.error('WindowsKeyboardService.hookupKeyboardHandlers: could not get inputPane');
                    return;
                }

                inputPane.addEventListener('showing', _ => this.onWindowsKeyboardUp);
                inputPane.addEventListener('hiding', _ => this.onWindowsKeyboardClose);            
            } catch (error) {
                this.logger.error(`WindowsKeyboardService.hookupKeyboardHandlers: ${error}`)
            }
        }
     
     /**
     * Raised when a Windows soft keyboard is opened
     */
        private onWindowsKeyboardUp() : void {
            try {
                this.logger.info("onWindowKeyboardUp");

                // Just half viewportHeight for now (until can find out how to get keyboard height - if even possible)
                let viewportHeight: number = window.innerHeight;
                let kbHeight = viewportHeight / 2;      
                this.logger.info(`viewportHeight: ${viewportHeight}`);
                const focusedElement = document.activeElement;
                if (!focusedElement) {
                    this.logger.info('WindowsKeyboardService.onWindowsKeyboardUp: Could not get focused input');
                    return;
                }

                let inputFieldOffsetFromBottomViewPort: number = viewportHeight - focusedElement.getBoundingClientRect().bottom;
                let inputScrollPixels = kbHeight - inputFieldOffsetFromBottomViewPort;

                const ionApp = document.getElementsByTagName("ion-app")[0];
                this.logger.info(ionApp ? "got app" : "not got app");

                // 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) {
                    const content = document.getElementsByTagName('ion-content');
                    if (!content || content.length == 0)
                        return;

                    const topMostContent = content[content.length - 1];
                    setTimeout(async () => {
                        let ionScroll = await topMostContent.getScrollElement();
                        ionScroll.animate({
                            scrollTop: ionScroll.scrollTop + inputScrollPixels
                        }, 300);
                    }, 300); // Matches scroll animation from css.         
                }
            } catch (error) {
                this.logger.error(`WindowsKeyboardService.onWindowKeyboardUp: ${error}`);
            }
        }

        /**
        * Raised when a Windows soft keyboard is closed 
        */
        private onWindowsKeyboardClose(): void {
            try {
                this.logger.info("WindowsKeyboardService.onWindowKeyboardClose");
                const ionApp = document.getElementsByTagName("ion-app")[0];      
                ionApp.style["margin-bottom"] = "0";
            } catch (error) {
                this.logger.error(`WindowsKeyboardService.onWindowKeyboardClose: ${error}`);
            }
        }
    }

我把它挂在app.component..

public async ngAfterViewInit(): Promise<void> {
        try {
            this.logger.info('AppComponent: ngAfterViewInit');
            this.windowsKeyboardService.hookupKeyboardHandlers();
        } catch (error) {
            this.logger.error(`AppComponent: ngAfterViewInit: ${error}`);
        }
    }

相关问题