bug: scroll assist needs improved keyboard estimation on web
Prequisites
- [X] I have read the Contributing Guidelines.
- [X] I agree to follow the Code of Conduct.
- [X] I have searched for existing issues that already report this problem, without success.
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
- 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/
- tap "Address Line 1"
- caret appears at the beginning of Address Line 1
- keyboard shows up
- 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.
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 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
Any update on this issue? It really kills the UX...
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.
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.
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.
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!
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.
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
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.
Beautiful, thank you for explaining! So here's the other better workaround then:
- Don't disable scrollAssist.
- Add extra blank space at the bottom of your ion-content
- 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 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.
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...
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 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.
Any updates on this issue?
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 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.
I have a PWA. On Android, the scrollAssist works relatively well, but not on ios/safari. Setting scrollAssist: false:
- On iOS it improves the behavior though it's not perfect (the top header is still gets hidden).
- 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.
still happens in 8.1.1