Repository navigation
Let iOS keyboard dismissal synchronize with scroll #57609
Copy link
Copy link
Open
Labels
P3Issues that are less important to the Flutter projectIssues that are less important to the Flutter projecta: fidelityMatching the OEM platforms betterMatching the OEM platforms bettera: text inputEntering text in a text field or keyboard related problemsEntering text in a text field or keyboard related problemsc: new featureNothing broken; request for a new capabilityNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to FlutterA detailed proposal for a change to Fluttercustomer: crowdAffects or could affect many people, though not necessarily a specific customer.Affects or could affect many people, though not necessarily a specific customer.engineflutter/engine related. See also e: labels.flutter/engine related. See also e: labels.f: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.platform-iosiOS applications specificallyiOS applications specificallyteam-iosOwned by iOS platform teamOwned by iOS platform teamtriaged-iosTriaged by iOS platform teamTriaged by iOS platform team
Description
Metadata
Metadata
Assignees
Labels
P3Issues that are less important to the Flutter projectIssues that are less important to the Flutter projecta: fidelityMatching the OEM platforms betterMatching the OEM platforms bettera: text inputEntering text in a text field or keyboard related problemsEntering text in a text field or keyboard related problemsc: new featureNothing broken; request for a new capabilityNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to FlutterA detailed proposal for a change to Fluttercustomer: crowdAffects or could affect many people, though not necessarily a specific customer.Affects or could affect many people, though not necessarily a specific customer.engineflutter/engine related. See also e: labels.flutter/engine related. See also e: labels.f: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.platform-iosiOS applications specificallyiOS applications specificallyteam-iosOwned by iOS platform teamOwned by iOS platform teamtriaged-iosTriaged by iOS platform teamTriaged by iOS platform team
Activity
xster commentedon Aug 27, 2020
The upstream visual symptom to fix is #19279
mleonhard commentedon Sep 5, 2021
furkansarihan commentedon Sep 6, 2021
@mleonhard This may help; https://pub.dev/packages/flutter_interactive_keyboard
mleonhard commentedon Sep 20, 2021
Dear Google Flutter Team,
I am preparing an app for release on Android & iOS. It has a small chat function. I am struggling to get the UX to match expectations for iOS users.
A common use-case for chat functions is to scroll up and consult a previous message while composing a new message. Users expect this on all platforms. Flutter currently makes this very hard to implement with acceptable UX on iOS:
onDragmode will hide the keyboard as soon as the user begins scrolling. This is jarring to iOS users who expect the keyboard to stay put.ListViewwithreverse: true, when the keyboard hides, the list jumps down. This is jarring, too. The user scrolls the desired information into view and taps the text box. The keyboard re-appears and the list jumps upward again, hiding the information they wanted to see. The user must learn to scroll the information to the bottom edge of the screen before tapping the text box. If they don't use the app frequently, they will forgot to do this and feel frustrated every time they use the Flutter app.ListView, the app must scroll the list up to the proper position when the keyboard appears. Figuring out how to do this is incredibly involved and may be impossible. Also, when the user begins scrolling and the keyboard disappears, they are left with the list scrolled half-way up the screen. They must move their finger down half the screen to continue scrolling. Additionally, when the user is scrolling and a new message arrives, the app tries to scroll to the bottom. This cancels their current scroll gesture. This is jarring. Therefore the non-reversedListViewrequires large amounts of code to work around Flutter's poor behavior when scrolling and showing/hiding the keyboard.donebutton by passingTextInputAction. This means the app cannot use thenewlineorsendbuttons which are much more useful.flutter_interactive_keyboardprovides the function requested in this issue. It is at v0.2.0. It has no tests. Every team desiring to use this in their production apps will need to review the code thoroughly.keyboard_actionsprovides buttons that appear above the keyboard to dismiss it. Some iOS apps use this mode. The row takes up vertical space on the screen. This makes the app harder to use on small phones and for folks who can't see very well and have their device zoomed or set to display large fonts. The module has no tests. Every team desiring to use this in their production apps will need to review the code thoroughly.Would you please implement this now?
Best Wishes,
Michael
CC: Flutter PM Tim Sneath @timsneath
CavalcanteLeo commentedon Nov 1, 2021
Tom3652 commentedon Dec 3, 2021
i am in the same situation as you @mleonhard, and as an iOS user myself i can tell that this is simply required as UX experience... Hopefully the upvotes should give some weight to the request as it is impacted many people :/
59 remaining items
matthew-carroll commentedon Nov 21, 2024
Thanks @ky1vstar - I noticed a property was added to
ListViewin Flutter (I think it was ListView) for this purpose. Of course, any scrollable might want that same behavior - not just aListViewand not just Flutter framework scrollables. Is there a composable widget where we can hand over aScrollControlleror something like that and have that scrollable automatically interface with the interactive dismissal you referenced?bbishdotdev commentedon Nov 24, 2024
gnprice commentedon Nov 24, 2024
You may be thinking of the
keyboardDismissBehaviorproperty. It's on theScrollViewbase class, so indeed you can use it on aCustomScrollViewor any other subclass.It doesn't solve this issue, though, only mitigate it. The ScrollViewKeyboardDismissBehavior enum has two values:
manual, the default, means don't do anything;onDragmeans that when the user starts dragging — even if they move only a small distance, and not near the keyboard — the keyboard gets dismissed. It doesn't sync with the user's finger; the drag kicks off an animation that then runs to completion, where the keyboard moves off the screen.Once a solution to this issue is built, a likely API for it would be to add another value to that enum. The hard part is building the solution, though.
gnprice commentedon Nov 24, 2024
Interesting, thanks @ky1vstar!
From a quick look at the code, it looks like the basic design is:
.interactiveWithAccessory.CupertinoInteractiveKeyboardwidget which uses those methods to maintain a rect corresponding to the widget's place on the screen.That seems like a pretty plausible approach, though definitely a hack.
Two questions: first, what's the function of the KeyboardManager class? How well would the plugin function without it? I ask because these lines look like potentially the sort of thing that would become not an option if Apple happened to notice it, and therefore isn't really an option for including in a widely-used framework like Flutter.
Second question: I notice the UIScrollView subclass sets a fixed content size:
Are those numbers significant — what happens if the actual content is taller and the user scrolls farther than that? Would the UIScrollView logic decide at some point that the user has reached the far end of the content, and change its behavior?
ky1vstar commentedon Nov 24, 2024
Hi, @gnprice
This customized ScrollPhysics tends to fix the situation when interactive dismissal is used together with reversed ScrollView (like in chat-like UI). Otherwise, ScrollView will be scrolled with doubled velocity, when keyboard is being interactively dismissed.
Short answer: the plugin would not function without KeyboardManager class.
Long answer: it is possible to make this plugin work without KeyboardManager class, but it would require significant effort.
So, actually, you can disable resizeToAvoidBottomInset in Scaffold, then add bottom viewInsets as the padding inside ScrollView and you can get rid of KeyboardManager. But it will not work with some Widget attached to the top of the keyboard (such as message input in chat-like UI), since KeyboardMessenger is used to find out the actual keyboard position, which is not reported by the system by default.
Not sure what to say about private API usage and Apple restrictions, but I believe I've seen some Apple's private API usage in Flutter already.
Hope, I've made this clearer 🙃
It doesn't matter, because the only requirement for interactive dismissal to happen is contentSize.height to be bigger than view port's height. If user reach the bottom of this scrollview, interactive dismissal is still gonna work.
itsjasur commentedon Jan 17, 2025
bbishdotdev commentedon Jan 17, 2025
I gave up and just simplified a clean, you touch anywhere outside the keyboard it closes. This also isn't the default, had to add a gesture detect area and handle some stuff in the chat specifically.
Any other solution I've tried at this point just creates a janky buggy experience which is way worse.
I pivoted when I realized ChatGPT and Grok close the keyboard once you send the message. This combined with tap anywhere outside to close is the best UX at the moment IMO...
abdalmonem commentedon Jan 19, 2025
@btbishop93 @CavalcanteLeo
This issue is really complicated , and its need a lot of work, till we can find the best optimal solution you can use this package:
https://pub.dev/packages/cupertino_interactive_keyboard
Its work for the most scenario cases, also there is a public Google document explain the issue and the suggested solutions and they cons and pros , (i can't find the link) but hope someone share the link here, it may helps to give you an overview of what we are dealing with it.
markymark2001 commentedon Feb 23, 2026
CavalcanteLeo commentedon Feb 23, 2026
markymark2001 commentedon Feb 23, 2026
Flutter iOS Interactive Keyboard: Take Screenshot and Handle Pointer …
Flutter iOS Interactive Keyboard: Handle Pointer Up (flutter-team-arc…
Flutter iOS Interactive Keyboard: Fixing Animation Issue (flutter-tea…
Flutter iOS Interactive Keyboard: Fixing Behavior Issue (flutter-team…