Skip to content

[iOS] TextField gets hidden by the keyboard due to out of sync animation #139054

Open

Description

@delfme

Is there an existing issue for this?

Steps to reproduce

This issue has been reproduced on old iphone models (tested on iphone 7 with iOS 15.7.9)

Sample code here:
https://github.com/delfme/flutter-native-text-input-repo/tree/3ef4459c0aad47b8d74d90340096e27844a18b9f

Expected results

Bottom inset should move in sync with keyboard native animation.

Actual results

There is a 4s animation delay, and during this time textfield is covered by the keyboard, see video from this comment (tested on iPhone 7, iOS 15.7.9) #138845 (comment)

Code sample

Sample here: https://github.com/delfme/flutter-native-text-input-repo/tree/3ef4459c0aad47b8d74d90340096e27844a18b9f

Screenshots or Video

RPReplay_Final1700799120.mp4

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 3.17.0-11.0.pre.9, on macOS 12.6.5 21G531 darwin-arm64, locale en-IT)
[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 14.0.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.2)
[✓] Connected device (3 available)
[✓] Network resources

Activity

  1. added
    in triagePresently being triaged by the triage team
    on Nov 28, 2023
  2. huycozy commented on Nov 28, 2023

    @huycozy
    Member

    Thanks for filing a separate issue. I triaged this at #138845 (comment), the issue can be reproduced with below minimal & complete sample code (your repository above is using 3rd plugin but it is actually not used in your sample code).

    Checking this again on the latest stable and master channels, I don't see this issue anymore, the TextField appears immediately. But if I observe with Devtools, I still see the first (and only) jank.

    Screen.Recording.2023-11-28.at.15.16.12.mov
    Sample code
    import 'package:flutter/material.dart';
    
    void main() async {
      runApp(
        MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
            useMaterial3: true,
          ),
          home: const DemoScreen(),
        ),
      );
    }
    
    class DemoScreen extends StatefulWidget {
      const DemoScreen({Key? key}) : super(key: key);
      @override
      State<DemoScreen> createState() => _DemoScreenState();
    }
    
    class _DemoScreenState extends State<DemoScreen> {
      final _controller = TextEditingController();
      final FocusNode _focusNode = FocusNode();
      late final _controllerNotifier = ValueNotifier(_controller.text.isEmpty);
    
      bool hasFocus = false;
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Chat Layout Demo'),
          ),
          body: SafeArea(
            child: Column(
              children: [
                Expanded(
                  child: GestureDetector(
                    onTap: () {
                      FocusScope.of(context).requestFocus(FocusNode());
                    },
                    child: Container(
                      color: Colors.brown,
                    ),
                  ),
                ),
                Container(
                  padding: const EdgeInsets.only(
                    bottom: 6.0,
                    top: 6.0,
                    left: 15.0,
                    right: 15.0,
                  ),
                  constraints: const BoxConstraints(
                    minHeight: 36,
                  ),
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      Expanded(
                        child: DecoratedBox(
                          decoration: BoxDecoration(
                            color: Colors.white,
                            borderRadius: BorderRadius.circular(19),
                            border: Border.all(
                              width: 0.5,
                              color: const Color(0xffCFCFCF),
                            ),
                          ),
                          child: Row(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              // Plus icon
                              Container(
                                margin: const EdgeInsets.fromLTRB(7, 6, 7, 6),
                                decoration: const BoxDecoration(
                                  color: Color(0xFF007AEA),
                                  shape: BoxShape.circle,
                                ),
                                width: 24,
                                height: 24,
                                child: const Icon(
                                  Icons.add,
                                  color: Colors.white,
                                ),
                              ),
                              const SizedBox(width: 9.0),
                              Expanded(
                                child: Padding(
                                  padding: const EdgeInsets.only(left: 0, right: 8),
                                  child: TextFormField(
                                    controller: _controller,
                                    keyboardType: TextInputType.multiline,
                                    textCapitalization: TextCapitalization.sentences,
                                    focusNode: _focusNode,
                                    onTap: () {},
                                    decoration: const InputDecoration(
                                      border: InputBorder.none,
                                      isDense: true,
                                      hintText: "Message",
                                    ),
                                  ),
                                ),
                              ),
                              ValueListenableBuilder<bool>(
                                valueListenable: _controllerNotifier,
                                builder: (ctx, value, child) {
                                  if (value) {
                                    return const Padding(
                                      padding: EdgeInsets.fromLTRB(8, 6, 8, 6),
                                      child: Icon(
                                        Icons.emoji_emotions_outlined,
                                        color: Color(0xFF9E9E9E),
                                      ),
                                    );
                                  }
                                  return const SizedBox.shrink();
                                },
                              )
                            ],
                          ),
                        ),
                      ),
                      const SizedBox(
                        width: 8,
                      ),
                      // Send button
                      Container(
                        height: 36,
                        width: 36,
                        decoration: const BoxDecoration(
                          color: Color(0xFF007AEA),
                          shape: BoxShape.circle,
                        ),
                        child: ValueListenableBuilder<bool>(
                          valueListenable: _controllerNotifier,
                          builder: (ctx, value, child) {
                            return GestureDetector(
                              onTap: () {
                                print("onTap Send");
                                _focusNode.unfocus();
                                hasFocus = false;
                              },
                              child: const Padding(
                                padding: EdgeInsets.fromLTRB(8, 7, 6, 7),
                                child: Icon(
                                  Icons.send,
                                  color: Colors.white,
                                ),
                              ),
                            );
                          },
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    flutter doctor -v (stable and master)
    [✓] Flutter (Channel stable, 3.16.1, on macOS 14.1 23B74 darwin-x64, locale en-VN)
        • Flutter version 3.16.1 on channel stable at /Users/huynq/Documents/GitHub/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 7f20e5d18c (9 hours ago), 2023-11-27 09:47:30 -0800
        • Engine revision 22b600f240
        • Dart version 3.2.1
        • DevTools version 2.28.3
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
        • Android SDK at /Users/huynq/Library/Android/sdk
        • Platform android-34, build-tools 34.0.0
        • ANDROID_HOME = /Users/huynq/Library/Android/sdk
        • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 15A507
        • CocoaPods version 1.13.0
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [!] Android Studio (version unknown)
        • Android Studio at /Applications/Android Studio Preview.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        ✗ Unable to determine Android Studio version.
        • Java version OpenJDK Runtime Environment (build 17.0.8+0-17.0.8b1000.22-10799086)
    
    [✓] Android Studio (version 2022.3)
        • Android Studio at /Applications/Android Studio Giraffe Patch 3.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    
    [✓] Android Studio (version 2022.2)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • android-studio-dir = /Applications/Android Studio.app/
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    
    [✓] VS Code (version 1.84.2)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.76.0
    
    [✓] Connected device (3 available)
        • RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64  • Android 11 (API 30)
        • macOS (desktop)  • macos            • darwin-x64     • macOS 14.1 23B74 darwin-x64
        • Chrome (web)     • chrome           • web-javascript • Google Chrome 119.0.6045.159
    
    [✓] Network resources
        • All expected network resources are available.
    
    ! Doctor found issues in 1 category.
    [!] Flutter (Channel master, 3.17.0-16.0.pre.34, on macOS 14.1 23B74 darwin-x64, locale en-VN)
        • Flutter version 3.17.0-16.0.pre.34 on channel master at /Users/huynq/Documents/GitHub/flutter_master
        ! Warning: `flutter` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
        ! Warning: `dart` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 2150424cee (20 minutes ago), 2023-11-27 18:23:21 -0800
        • Engine revision 96137d05fa
        • Dart version 3.3.0 (build 3.3.0-169.0.dev)
        • DevTools version 2.30.0-dev.4
        • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
        • Android SDK at /Users/huynq/Library/Android/sdk
        • Platform android-34, build-tools 34.0.0
        • ANDROID_HOME = /Users/huynq/Library/Android/sdk
        • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 15A507
        • CocoaPods version 1.13.0
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [!] Android Studio (version unknown)
        • Android Studio at /Applications/Android Studio Preview.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        ✗ Unable to determine Android Studio version.
        • Java version OpenJDK Runtime Environment (build 17.0.8+0-17.0.8b1000.22-10799086)
    
    [✓] Android Studio (version 2022.3)
        • Android Studio at /Applications/Android Studio Giraffe Patch 3.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    
    [✓] Android Studio (version 2022.2)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • android-studio-dir = /Applications/Android Studio.app/
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    
    [✓] VS Code (version 1.84.2)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.76.0
    
    [✓] Connected device (3 available)
        • RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64  • Android 11 (API 30)
        • macOS (desktop)  • macos            • darwin-x64     • macOS 14.1 23B74 darwin-x64
        • Chrome (web)     • chrome           • web-javascript • Google Chrome 119.0.6045.159
    
    [✓] Network resources
        • All expected network resources are available.
    
    ! Doctor found issues in 2 categories.

    Do you notice this issue on your another iOS physical device?

  3. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Nov 28, 2023
  4. delfme commented on Nov 28, 2023

    @delfme
    Author

    With iphone 13 pro iOS 16.3.1, Im sometimes hit by a shake on the first opening, then it is smooth. Probably it is that janky initial frame.

    Can someone make time for this and the android equivalent?
    I do understand it is not easy, but we cannot show to users a shaking textfield.

  5. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Nov 28, 2023
  6. huycozy commented on Nov 29, 2023

    @huycozy
    Member

    Checking this on Android, there's not much jank either but raster can be easily seen when the keyboard pops up. At that time, the input chat view (on the keyboard) will have a slight jerking effect. And I think it could be similar to #120435.

    Checking again on iOS, I indeed no longer see the original issue (4s animation delay). However, sometimes a slight jerking effect on the chat view input still exists when the keyboard pops up; no jank at that time, and it is much less raster than Android (mostly just UI frames). I will label the issue for other's input to see if there's a way to explore this more clearly.

    Demo video iOS (iPhone 7, iOS 15.8)
    RPReplay_Final1701232594.mp4
    flutter doctor -v (stable and master)
    [✓] Flutter (Channel stable, 3.16.1, on macOS 14.1 23B74 darwin-x64, locale en-VN)
        • Flutter version 3.16.1 on channel stable at /Users/huynq/Documents/GitHub/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 7f20e5d18c (9 hours ago), 2023-11-27 09:47:30 -0800
        • Engine revision 22b600f240
        • Dart version 3.2.1
        • DevTools version 2.28.3
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
        • Android SDK at /Users/huynq/Library/Android/sdk
        • Platform android-34, build-tools 34.0.0
        • ANDROID_HOME = /Users/huynq/Library/Android/sdk
        • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 15A507
        • CocoaPods version 1.13.0
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [!] Android Studio (version unknown)
        • Android Studio at /Applications/Android Studio Preview.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        ✗ Unable to determine Android Studio version.
        • Java version OpenJDK Runtime Environment (build 17.0.8+0-17.0.8b1000.22-10799086)
    
    [✓] Android Studio (version 2022.3)
        • Android Studio at /Applications/Android Studio Giraffe Patch 3.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    
    [✓] Android Studio (version 2022.2)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • android-studio-dir = /Applications/Android Studio.app/
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    
    [✓] VS Code (version 1.84.2)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.76.0
    
    [✓] Connected device (3 available)
        • RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64  • Android 11 (API 30)
        • macOS (desktop)  • macos            • darwin-x64     • macOS 14.1 23B74 darwin-x64
        • Chrome (web)     • chrome           • web-javascript • Google Chrome 119.0.6045.159
    
    [✓] Network resources
        • All expected network resources are available.
    
    ! Doctor found issues in 1 category.
    [!] Flutter (Channel master, 3.17.0-17.0.pre.47, on macOS 14.1 23B74 darwin-x64, locale en-VN)
        • Flutter version 3.17.0-17.0.pre.47 on channel master at /Users/huynq/Documents/GitHub/flutter_master
        ! Warning: `flutter` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
        ! Warning: `dart` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 7a0508e5de (10 minutes ago), 2023-11-28 22:01:04 -0500
        • Engine revision 4beaa1195b
        • Dart version 3.3.0 (build 3.3.0-170.0.dev)
        • DevTools version 2.30.0-dev.4
        • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
        • Android SDK at /Users/huynq/Library/Android/sdk
        • Platform android-34, build-tools 34.0.0
        • ANDROID_HOME = /Users/huynq/Library/Android/sdk
        • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 15A507
        • CocoaPods version 1.13.0
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [!] Android Studio (version unknown)
        • Android Studio at /Applications/Android Studio Preview.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        ✗ Unable to determine Android Studio version.
        • Java version OpenJDK Runtime Environment (build 17.0.8+0-17.0.8b1000.22-10799086)
    
    [✓] Android Studio (version 2022.3)
        • Android Studio at /Applications/Android Studio Giraffe Patch 3.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    
    [✓] Android Studio (version 2022.2)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • android-studio-dir = /Applications/Android Studio.app/
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    
    [✓] VS Code (version 1.84.2)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.76.0
    
    [✓] Connected device (4 available)
        • RMX2001 (mobile) • EUYTFEUSQSRGDA6D                         • android-arm64  • Android 11 (API 30)
        • iPhone (mobile)  • d9a94afe2b649fef56ba0bfeb052f0f2a7dae95e • ios            • iOS 15.8 19H370
        • macOS (desktop)  • macos                                    • darwin-x64     • macOS 14.1 23B74 darwin-x64
        • Chrome (web)     • chrome                                   • web-javascript • Google Chrome 119.0.6045.159
    
    [✓] Network resources
        • All expected network resources are available.
    
    ! Doctor found issues in 2 categories.
  7. added
    a: text inputEntering text in a text field or keyboard related problems
    platform-iosiOS applications specifically
    engineflutter/engine related. See also e: labels.
    c: performanceRelates to speed or footprint issues (see "perf:" labels)
    team-iosOwned by iOS platform team
    and removed
    in triagePresently being triaged by the triage team
    on Nov 29, 2023
  8. delfme commented on Nov 29, 2023

    @delfme
    Author

    Thx @huycozy I think you used the best words.
    On android: jerking effect and delay
    On iOS: jerking effect

    On iOS, an important fix was merged lately from @cyanglaz and @luckysmg It would be great to know if the residual issue depends on an edge case not covered by the fix or maybe it is something unrelated that must be addressed elsewhere.

    We are insisting much on this issue coz we have a premium messaging app that we cannot ship with this bug. But in general, 90% of apps have this UI and bug makes them look “cheap”.

  9. 6 remaining items

  10. added and removed on Mar 12, 2024
  11. added and removed
    engineflutter/engine related. See also e: labels.
    on Mar 18, 2024
  12. kkoskenvirta commented on Jun 7, 2024

    @kkoskenvirta

    This seems to be a possible reason with the problem noticed in my issue for WoltModalSheet.
    woltapp/wolt_modal_sheet#222 (comment)

    I got also made a more simple demo of the problem here. It suddenly starts to work and then reggresses back to the lag irregularly.

    RPReplay_Final1717737630.mp4
  13. loic-sharma commented on Aug 21, 2025

    @loic-sharma
    Member

    cc @LongCatIsLooong are you able to reproduce this issue?

  14. anthonytdavis80 commented on Aug 23, 2025

    @anthonytdavis80

    @loic-sharma you can reproduce the issue with google NotebookLM app (see attached video). Both iOS and android apps have this issue when textfield is placed at the bottom of the screen.

    The problem:

    • Flutter receives keyboard height changes via events (viewInsets), but not frame-by-frame timing info of the OS animation. That’s why the content jump appears “bumpy”: Flutter updates layout after each frame, but it can’t perfectly follow the native keyboard curve.

    Potential Fix:

    • True frame-perfect synchronization with the OS keyboard animation requires changes in the engine/embedders so that Flutter gets per-frame timing from the OS, like it does on macOS for window resizing.

    GPT suggestions:

    • iOS: You’d need to hook into the native keyboard animation APIs (UIKeyboardWillShowNotification, UIKeyboardFrameEndUserInfoKey, and animation curves) and send frame-by-frame updates to Flutter.

    • Android: You’d have to intercept InsetsAnimation.Callback or similar APIs (depending on Android version) and push interpolated insets to Flutter each frame.

    • Flutter engine side: The engine would need a new channel or mechanism to animate viewInsets in sync with the OS animation rather than just sending the final height.

    • Framework side: Widgets that use MediaQuery.viewInsets would automatically follow the smoother animation.

    A skilled Flutter engineer could do it, it’s not a fundamental limitation.

    1. iOS Embedder

    Goal: Send Flutter updates on keyboard frame for each animation step.

    Steps:

    1. Listen to keyboard notifications
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(keyboardWillChangeFrame(_:)),
        name: UIResponder.keyboardWillChangeFrameNotification,
        object: nil
    )
    
    1. Extract animation info:
    @objc func keyboardWillChangeFrame(_ notification: Notification) {
        guard let info = notification.userInfo,
              let frameEnd = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
              let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double,
              let curve = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else { return }
        
        // Convert curve to UIView.AnimationOptions
        let options = UIView.AnimationOptions(rawValue: curve << 16)
        
        animateKeyboardTo(frameEnd: frameEnd, duration: duration, options: options)
    }
    
    1. Send per-frame updates
    • Instead of just sending the final keyboard height, interpolate frame-by-frame using a display link:
    var displayLink: CADisplayLink?
    var startHeight: CGFloat = 0
    var endHeight: CGFloat = 0
    var elapsed: TimeInterval = 0
    var totalDuration: TimeInterval = 0
    
    func animateKeyboardTo(frameEnd: CGRect, duration: Double, options: UIView.AnimationOptions) {
        startHeight = currentKeyboardHeight
        endHeight = frameEnd.height
        totalDuration = duration
        elapsed = 0
    
        displayLink?.invalidate()
        displayLink = CADisplayLink(target: self, selector: #selector(updateKeyboardFrame))
        displayLink?.add(to: .current, forMode: .default)
    }
    
    @objc func updateKeyboardFrame() {
        elapsed += displayLink!.duration
        let progress = min(1, elapsed / totalDuration)
        let interpolatedHeight = startHeight + CGFloat(progress) * (endHeight - startHeight)
        
        // Send height to Flutter via platform channel
        flutterChannel.invokeMethod("keyboardHeight", arguments: interpolatedHeight)
        
        if progress >= 1 {
            displayLink?.invalidate()
            displayLink = nil
        }
    }
    

    2. Android Embedder

    Goal: Use WindowInsetsAnimation.Callback to receive smooth inset changes.

    Set up callback:

    ViewCompat.setWindowInsetsAnimationCallback(flutterView,
        object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_CONTINUE_ON_SUBTREE) {
            override fun onProgress(
                insets: WindowInsetsCompat,
                runningAnimations: MutableList<WindowInsetsAnimationCompat>
            ): WindowInsetsCompat {
                val keyboardHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
                // Send to Flutter via MethodChannel
                flutterChannel.invokeMethod("keyboardHeight", keyboardHeight)
                return insets
            }
        }
    )
    

    Notes:

    • Works for Android 11+ (API 30).
    • Older versions can use ViewTreeObserver.OnGlobalLayoutListener and interpolate manually.

    3. Flutter Engine / Framework

    Goal: Update viewInsets dynamically so widgets react in real time.

    1. Custom platform channel
    • Name: "keyboardHeight" (as above).
    • Send height updates per frame.
    1. Update MediaQuery in Flutter
    StreamController<double> _keyboardHeightStream = StreamController.broadcast();
    
    MethodChannel('keyboardHeight').setMethodCallHandler((call) async {
      if (call.method == 'keyboardHeight') {
        _keyboardHeightStream.add(call.arguments as double);
      }
    });
    
    StreamBuilder<double>(
      stream: _keyboardHeightStream.stream,
      builder: (context, snapshot) {
        final bottomInset = snapshot.data ?? 0;
        return Padding(
          padding: EdgeInsets.only(bottom: bottomInset),
          child: MyContent(),
        );
      },
    );
    
    1. Optional: Replace MediaQuery viewInsets entirely for seamless widget updates.

    4. Caveats & Maintenance

    • You’re now diverging from upstream Flutter, so future updates could break this.
    • Performance: sending updates every frame must be efficient, especially on Android.
    • Some edge cases: split keyboard, floating keyboard, rotation changes.

    💡 Result:

    Widgets using MediaQuery.viewInsets or bottom padding will now animate in perfect sync with the OS keyboard, eliminating the “bumpy jump.”

    If you want, I can also write a ready-to-use Flutter plugin + embedder patch skeleton that implements this fully for iOS + Android. It would be almost plug-and-play for your apps.

    ScreenRecording_08-23-2025.21-22-28_1.mov
  15. added
    P2Important issues not at the top of the work list
    on Sep 25, 2025
  16. justinmc commented on Sep 25, 2025

    @justinmc
    Contributor

    CC @LongCatIsLooong from triage again, see #139054 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: animationAnimation APIsa: text inputEntering text in a text field or keyboard related problemsc: performanceRelates to speed or footprint issues (see "perf:" labels)platform-iosiOS applications specificallyteam-text-inputOwned by Text Input teamtriaged-text-inputTriaged by Text Input team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions