ionic-framework icon indicating copy to clipboard operation
ionic-framework copied to clipboard

bug: scroll assist needs improved keyboard estimation on web

Open ippeiukai opened this issue 4 years ago • 22 comments

Prequisites

Ionic Framework Version

  • [ ] v4.x
  • [X] v5.x
  • [ ] v6.x

Current Behavior

On iOS Safari (and as an app with "Add to Home Screen"), there is an uncomfortable pause when switching between inputs.

Expected Behavior

When tapping another input on the page to switch focus, there should be no delay when no scrolling is required and keyboard remains open.

Steps to Reproduce

  1. Open following app in Safari on iOS/iPadOS device or simulator:
    • with "Device Preview" QR-code on https://dashboard.ionicframework.com/preview/f7e6e842/mbb6khxjl9
    • or directly at https://mbb6khxjl9.appflowapp.com/
  2. tap "Address Line 1"
    • caret appears at the beginning of Address Line 1
    • keyboard shows up
  3. tap "Address Line 2"
    • caret disappears from "Address Line 1"
    • keyboard stays open
    • -- awkward pause lasting about a second --
    • caret appears at the beginning of Address Line 2

reproducible on:

  • iPad Air 2 (iPadOS 14.6)
  • iPhone 12 mini (iOS 14.4; on Simulator)

Code Reproduction URL

https://github.com/ippeiukai/ionic-safari-input-issue-23664

Ionic Info

$ ionic info

Ionic:

   Ionic CLI                     : 5.4.16 (/■■■■■■■/lib/node_modules/ionic)
   Ionic Framework               : @ionic/angular 5.6.11
   @angular-devkit/build-angular : 12.1.2
   @angular-devkit/schematics    : 12.1.2
   @angular/cli                  : 12.1.2
   @ionic/angular-toolkit        : 4.0.0

Capacitor:

   Capacitor CLI   : 3.1.1
   @capacitor/core : 3.1.1

Utility:

   cordova-res : not installed
   native-run  : 1.4.0

System:

   NodeJS : v12.22.3 (/■■■■■■■/bin/node)
   npm    : 6.14.13
   OS     : macOS Catalina


  ────────────────────────────────────────────────────────────

          Ionic CLI update available: 5.4.16 → 6.11.8
                                
     The package name has changed from ionic to @ionic/cli!
                                
             To update, run: npm uninstall -g ionic
                 Then run: npm i -g @ionic/cli

  ────────────────────────────────────────────────────────────

Additional Information

Observing the DOM with Web Inspector suggests the relocateInput hack is being executed when "Address Line 2" is tapped, although there is no scrolling happening and the keyboard is already open and remains open. https://github.com/ionic-team/ionic-framework/blob/v5.6.11/core/src/utils/input-shims/hacks/common.ts#L14

Our production app (which uses @ionic/angular 5.3.3) is affected and one of the views has severely degraded user experience as a result. Any help or workaround would be greatly appreciated.

ippeiukai avatar Jul 21 '21 06:07 ippeiukai

Thanks for the issue. The problem here is that we need to approximate the height of the keyboard, and we appear to be overestimating. When we adjust the input, we assume that the content will scroll, so we wait for that to finish. There is a 1000ms fallback setTimeout in case there is no scrolling, so that is likely what you are running into here: https://github.com/ionic-team/ionic-framework/blob/7315e0157b917d2e3586c64f8082026827812943/core/src/utils/input-shims/hacks/scroll-assist.ts#L142

While we can use the Ionic Keyboard Events to detect the exact height of the keyboard, this event does not fire until the keyboard is fully on screen, leading to a ~300ms delay so we opt to estimate the height instead to make the scroll assist utility more responsive.

A possible solution is to change this "Safe area" value: https://github.com/ionic-team/ionic-framework/blob/7315e0157b917d2e3586c64f8082026827812943/core/src/utils/input-shims/hacks/scroll-data.ts#L37 though we need to make sure that it does not regress https://github.com/ionic-team/ionic-framework/issues/21912.

This does not impact Cordova/Capacitor apps because we can use the native Keyboard plugin to get the height of the keyboard before it even opens.

liamdebeasi avatar Jul 21 '21 13:07 liamdebeasi

@liamdebeasi By any chance assuming ‘the keyboard being closed when an input gets focus’ is affecting the calculation for switching focus while the keyboard is already open? I didn’t understand the logic fully, but this statement in the comment sounded suspicious: https://github.com/ionic-team/ionic-framework/blob/7315e0157b917d2e3586c64f8082026827812943/core/src/utils/input-shims/hacks/scroll-data.ts#L50-L51

ippeiukai avatar Jul 21 '21 14:07 ippeiukai

Any update on this issue? It really kills the UX...

ekhmoi avatar Jan 26 '22 12:01 ekhmoi

Any update on this issue? It really kills the UX...

Still happening on Ionic version 6. I found out that even when I set the mode on material design but access the app on an iOS, this bug still exists.

RZMiRaN avatar Feb 26 '22 10:02 RZMiRaN

I had to switch to Angular Material Inputs to deal with this.

If someone from Ionic team would point me in the right direction I can investigate the issue.

ekhmoi avatar Feb 26 '22 11:02 ekhmoi

The code that handles scroll assist is here: https://github.com/ionic-team/ionic-framework/blob/7315e0157b917d2e3586c64f8082026827812943/core/src/utils/input-shims/hacks/scroll-assist.ts

You can also disable scroll assist for now by setting scrollAssist: false in your Ionic config. This allows you to avoid this behavior while continuing to use ion-input.

liamdebeasi avatar Feb 28 '22 13:02 liamdebeasi

Yep that solved it for me! ionic v6, stenciljs, capacitor app

setupConfig({
  scrollAssist: false,
});

What feature am I missing out on by setting scrollAssist to false? Scrolling seems fine, and the input focus is snappy as the keyboard appears!

corysmc avatar Mar 11 '22 02:03 corysmc

When an ion-input is at the bottom of the screen, it will get covered by the keyboard as the input will not be scrolled into view if scrollAssist: false.

liamdebeasi avatar Mar 11 '22 14:03 liamdebeasi

Hmm, I'm finding the opposite of that. scrollAssist: false is what fixed it for me, so that when the keyboard opens the input focuses and moves into view. e.g.:

scrollAssist:false

https://user-images.githubusercontent.com/6452188/157889311-99b6df50-d18a-4a14-8cff-e3fd66de9378.mov

default

https://user-images.githubusercontent.com/6452188/157889338-83f98464-f26c-4201-a5c3-b11cd5ffb24c.mov

corysmc avatar Mar 11 '22 14:03 corysmc

When you disable scrollAssist, the native browser behavior kicks in and scrolls the input into view. However, it does so by shifting the entire view instead of only scrolling the content. Notice in your first video that the header in the modal moves off screen when you focus the input.

liamdebeasi avatar Mar 11 '22 14:03 liamdebeasi

Beautiful, thank you for explaining! So here's the other better workaround then:

  1. Don't disable scrollAssist.
  2. Add extra blank space at the bottom of your ion-content
  3. Makes for some awkward space below your content that keeps scrolling, but at least we can show the input when the keyboard is up. Per @liamdebeasi comment - notice in the video below the view isn't shifted (modal header is NOT cut off) the scroll to input happens within the ion-content.

https://user-images.githubusercontent.com/6452188/157893948-31c7c837-e5ee-4663-b681-a0a42f8a2554.mov

corysmc avatar Mar 11 '22 15:03 corysmc

@corysmc Second this, "scrollAssist: false" fixes it. Despite any repercussions caused in iOS or Android builds. I refuse to "add blank space at bottom of your ion-content". Seems silly even if it works. This is not our fault and the failure of ionic dev team. Should be properly fixed truly. I refuse to hinder UX design at my own cost.

https://github.com/ionic-team/ionic-framework/issues/13414 The link above shows that this has been an issue since 2017. Of course, Ionitron Bot closed it, nothing new there. This is a problem with ionic dev team and they seem to have refused to provide a solid fix for it. If I am wrong and there is an actual fix besides this, please correct me @liamdebeasi or let me know. Just stating facts from what I have seen since 2017.

pgmoftexas avatar Mar 19 '22 01:03 pgmoftexas

I have updated to ionic 6 yesterday and since then the same issue occurs.

As soon as the input is near the end, it gets delayed very badly for 1-2 sec before the input is available. If I click on any input on the top page it is focused immediatly. If any one has a good solution please let me know. I will try to figure something out as I haven't tested it on the device yet. If the error still occurs there, lets see...

nosTa1337 avatar Jan 18 '23 13:01 nosTa1337

I have updated to ionic 6 yesterday and since then the same issue occurs.

As soon as the input is near the end, it gets delayed very badly for 1-2 sec before the input is available. If I click on any input on the top page it is focused immediatly. If any one has a good solution please let me know. I will try to figure something out as I haven't tested it on the device yet. If the error still occurs there, lets see...

welcome to the club :)

pgmoftexas avatar Jan 25 '23 15:01 pgmoftexas

@pgmoftexas it seems like its working on the device for me. Havent made a production build yet but on the debug versions the issue has not occured yet.

nosTa1337 avatar Jan 25 '23 16:01 nosTa1337

Any updates on this issue?

Artfloriani avatar Nov 12 '23 15:11 Artfloriani

Does this happen in Ionic 7.x too, or is it enough to update from 6.x to 7.x, although it could be overkill, depending on the app?

lucrus73 avatar Jan 28 '24 16:01 lucrus73

@lucrus73 I'm on Ionic 7.0.0 and it still occurs. Huge pain, even the workaround that others have mentioned doesn't work for me. Heavily making me consider developing native because of this bug, makes everything feel janky. I've noticed some lag also occurs similarly for buttons, on first click its laggy then after its fine.

elitebyte avatar Feb 22 '24 09:02 elitebyte

I have a PWA. On Android, the scrollAssist works relatively well, but not on ios/safari. Setting scrollAssist: false:

  1. On iOS it improves the behavior though it's not perfect (the top header is still gets hidden).
  2. On Android/chrome it works but when I click back on my form somewhere, the screen jumps to a different position. Because of how badly the scrollAssist works in iOS, I've disabled it for now and will live with the jumpiness on Android.

ntorrey avatar Feb 25 '24 17:02 ntorrey

still happens in 8.1.1

merto20 avatar Jun 01 '24 15:06 merto20