ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
50.9k stars 13.52k forks source link

bug: ion-input on mobile devices causes height shrinkage to two elements after upgrade to v7 #28014

Closed pjc2007 closed 1 year ago

pjc2007 commented 1 year ago

Prerequisites

Ionic Framework Version

v7.x

Current Behavior

After upgrading Ionic framework to v7, I have a component where when focusing on an ion-input on a touch device, both the ion-content, and the next parent element seem to shrink to allow for the keyboard.

I did not have this issue in v6.

Running on an iphone emulator, here is the page in question without any input focus. Note the red border around the ion-content, and there is also a green border around the next div down...

image

And the next div under the ion-content has a green border.

image

Both have full height as expected.

Now if I focus into an input, the ion-content's height shrinks to the correct size, buy but div has also had the height shrunk...

image

And we can see from it's styes that the height in css is set to 100%..

image

Expected Behavior

For setting the focus to an ion-input to not apply a height adjustment to more than one element

Steps to Reproduce

See sample application, though it is hard to see unless running on a device (or simulator) so can see the virtual keyboard, but if run using the device emulation will see the heigth shrink.

Code Reproduction URL

https://github.com/pjc2007/input-jump-v7

Ionic Info

Ionic:

Ionic CLI : 6.20.1 (/usr/local/lib/node_modules/@ionic/cli) Ionic Framework : not installed @angular-devkit/build-angular : 16.1.5 @angular-devkit/schematics : 16.1.5 @angular/cli : 16.1.5 @ionic/angular-toolkit : 10.0.0

Cordova:

Cordova CLI : 11.0.0 Cordova Platforms : android 11.0.0, ios 6.2.0 Cordova Plugins : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 5.0.0, (and 12 other plugins)

Utility:

cordova-res : 0.15.4 native-run (update available: 1.7.2) : 1.7.1

System:

Android SDK Tools : 26.1.1 (/Users/development/Library/Android/sdk) ios-deploy : 1.11.4 ios-sim : 8.0.2 NodeJS : v16.15.0 (/usr/local/bin/node) npm : 8.5.5 OS : macOS Xcode : Xcode 14.2 Build version 14C18

Additional Information

No response

liamdebeasi commented 1 year ago

Thanks for the report. Can you please clarify your steps to reproduce? I ran your app on an iPhone 14, and the webview resizes correctly when opening the keyboard:

IMG_0077

pjc2007 commented 1 year ago

Hi thanks for looking, I thought I had reproduced in the sample app, but I will need to rechecked perhaps I have missed some step in it to repo what is happening in my production app. I'll try to get onto this in the next day or so.

pjc2007 commented 1 year ago

While looking for differences in my production app, I uninstalled cordova-plugin-ionic-keyboard, and now it seems to have fixed the problem. Focus to the input now causes the height to shrink just enough for the keyboard. So it still seems to shrink without cordova-plugin-ionic-keyboard at all (at least in the ios slmulator)

Does this mean we don't need (should not use) cordova-plugin-ionic-keyboard anymore, as the apps height now seem to be adjusted by something else?

liamdebeasi commented 1 year ago

The cordova-plugin-ionic-keyboard plugin will change the resize behavior of the webview: https://github.com/ionic-team/cordova-plugin-ionic-keyboard#keyboardresizemode-for-ios-only

For example, a keyboard resize of "native" will cause the entire webview to be resized while a value of "ionic" will cause only the ion-app element to be resized. The layout shifts will be different based on the value you choose. This plugin is not deprecated as far as I am aware, though the development team behind that plugin is primarily focused on Capacitor instead of Cordova.


Focus to the input now causes the height to shrink just enough for the keyboard. So it still seems to shrink without cordova-plugin-ionic-keyboard at all (at least in the ios slmulator)

Ionic has a "scroll assist" utility that scrolls the ion-content such that the focused input is not hidden by the keyboard. Input scroll position should be adjusted, but the dimensions of the input should not change. Can you please provide a code sample that reproduces the issue so we can take a look?

pjc2007 commented 1 year ago

I do plan to swap to Capacitor in the future I just need to work out build scripts for build machine.

But for now, if you get the latest version of the sample project I have added Cordova, and including the keyboard plugin.

I build using

ionic cordova build ios --configuration production --release

the open the project in xcode, and run on the simulator

Now if you open, and click on an input near the bottom (e.g. second last), you will now see the container div has shrunk to very small...

image

I now removed the keyboard plugin...

ionic cordova plugin remove cordova-plugin-ionic-keyboard

Now I click say the second input from the bottom, and I get...

image

However, I just noticed, if I now click in the input a second time, it now shrinks the height again....

image

liamdebeasi commented 1 year ago

The view setup here is a bit unusual since it creates a custom scroll container within ion-content and it also tries to re-create the footer behavior within the content. There seems to be some interaction going on with cordova-plugin-ionic-keyboard here, but I'm not able to pinpoint anything inside of Ionic Framework that could be causing this.

It looks like your #input-container element has a height of 0. It's possible that ion-input is changing height as a result of the parent container shrinking, but ion-input does not appear to be contributing to the parent container shrinking:

image

This behavior can be avoided by restructuring your view a bit:

  1. To start, the footer button should be in an ion-footer. This allows you to remove the #container logic.
  2. Next, remove the nested scrolling logic. Ionic has logic built-in to ensure inputs are not hidden by the keyboard, but that only works if the inputs are scrolled on ion-content.

Your code should look something like this:

home.page.html

<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      Page 2
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-button routerLink="/home">Home</ion-button>
<ion-content [fullscreen]="true">
  <app-inputs></app-inputs>
</ion-content>

<ion-footer>
  <ion-toolbar>
    <ion-button>Footer Button</ion-button>
  </ion-toolbar>
</ion-footer>

inputs.component.html

<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>
<ion-input></ion-input>

The end result should look something like the following video, which seems to be more in line with what you are expecting to see.

https://github.com/ionic-team/ionic-framework/assets/2721089/eba88bb0-e3ca-4158-9e5f-aef8ef40b982

As I mentioned above, I am not able to identify anything in Ionic Framework that could be causing this behavior, so I am going to close this. Let me know if you have any questions.

pjc2007 commented 1 year ago

Hi thanks for looking at this. Of course this sample app is a bit contrived, I have just tried to mimic the rough structure of my real app. The real app is not so simple as above, the ion-content actually holds a swiper, and each page of the swiper is a component. Each component then has a form with various inputs. Some may just happen to have a button at the button, but others may not, so I could not use a top level footer here.

What I have found , going back to my real app, is it is the padding-bottom of the main part of the ion-content that is causing the issue.

If I disable this in dev tools, then everything work perfectly....

image.

So here is a screen shot of my real app, with this disabled (and the ionic cordova keyboard plugin installed)...

image

With this padding-bottom disabled, it all works perfectly, i.e. clicking from on input to the other etc. The keyboard plugin looks after the resizing, and seems to get it right. This padding is set here at content.scss

image

Perhaps something with the calculation here change in v7 (as I Have never had this problem before over multiple previous versions until my upgrade)

I have added the following to global.sccs...

ion-content::part(scroll) {
  padding-bottom: 0 !important;
}

And this seems to have fixed it (though always a bit worried adding such overrides to internal parts). Not sure why we would no wneed to do this in v7 (could it be tested more with a capacitor keyboard plugin that perhaps works differently?)

liamdebeasi commented 1 year ago

Ionic will add padding to the bottom of the content so elements that are closed to the bottom of the container do not get stuck under the keyboard. I recommend trying the Capacitor Keyboard plugin, but you can also set scrollPadding: false in the Ionic config to disable the scroll padding if you are unable to migrate at the moment.

pjc2007 commented 1 year ago

Thanks for that, I did not seem to be able to get the scrollPadding: false to work, It does not seem to be an option in the doco?

At any rate, tried both...

{
  "name": "my app",
  "integrations": {
    "cordova": {}
  },
  "type": "angular",
  "scrollPadding": "false"
}

and

{
  "name": "my app",
  "integrations": {
    "cordova": {}
  },
  "type": "angular",
  "scrollPadding": false
}

(false as a bool and a string)

But I still get the padding bottom...

image

So I still seem to need to use

ion-content::part(scroll) {
  padding-bottom: 0 !important;
}

Looking at the Cordova keyboard source, I can on the JS side it just seems to resize one of the parent elements, so this by itself seems to be enough (though I need to test this on a version I have running in Windows WebView 2 that does not use Cordova).

Yes, I need to check all plugins I use are available and work out build scripts for Capacitor (it does not have the build scripts as we get with Cordova), and then I will cross over to it.

liamdebeasi commented 1 year ago

You need to set scrollPadding in the Ionic config not the Capacitor config since this is an Ionic Framework feature: https://github.com/ionic-team/ionic-framework/blob/c782c91185dd00ed959cc607a386cb75b590d962/core/src/utils/config.ts#L210

It's an undocumented API there for debugging purposes such as this where you want to identify if something is the root cause of a problem.

ionitron-bot[bot] commented 11 months ago

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 Ionic, please create a new issue and ensure the template is fully filled out.