Skip to content

[iOS] Keyboard remains visible after quick app switch while TextField no longer has focus #189051

Closed

Description

@hoyahozz

Steps to reproduce

  1. Clone and run the sample project:
git clone https://github.com/hoyahozz/ios-keyboard-stuck-after-app-switch.git
cd ios-keyboard-stuck-after-app-switch
flutter pub get
flutter run -d <ios-device-id>
  1. Launch the app on iOS.
  2. Tap any TextField.
  3. Keep the iOS keyboard visible.
  4. Quickly switch to another app using the iOS home indicator.
  5. Return to the Flutter app.
  6. Check the status panel and debug logs.

Expected results

Flutter should keep text input state consistent after returning to the app.

Either:

  • the keyboard is dismissed when no TextField has focus, or
  • the focused TextField remains focused while the keyboard is visible.

The app should not return with no TextField focused while the iOS keyboard and keyboard inset are visible.

Actual results

After returning to the app, no sample TextField is focused, but the iOS keyboard becomes visible again and viewInsets.bottom returns to the keyboard height.

In the captured logs, viewInsets.bottom briefly goes to 0.0 while the app is paused. During foregrounding, it grows again before resumed, and by the time the app is resumed the primary focus is a route/modal focus scope, not a TextField.

Example observed state:

lifecycle=AppLifecycleState.resumed
focus after lifecycle change: primaryFocus=_ModalScopeState<dynamic> Focus Scope; textFieldFocus=first=false, second=false, multiline=false
metrics after lifecycle change: viewInsets.bottom=physical=911.3, logical=303.8

This looks like the Flutter focus state and iOS text input / keyboard inset state become inconsistent after a quick app switch.

This may be related to #144463, but this case is triggered by quick app switching instead of iOS Look Up.

Code sample

Code sample

Sample repository:

https://github.com/hoyahozz/ios-keyboard-stuck-after-app-switch

The sample uses only Flutter TextField widgets and logs:

  • AppLifecycleState
  • FocusManager.instance.primaryFocus
  • each sample TextField focus state
  • FlutterView.viewInsets.bottom
  • MediaQuery.viewInsets.bottom

Main sample file:

https://github.com/hoyahozz/ios-keyboard-stuck-after-app-switch/blob/main/lib/main.dart

Screenshots or Video

Screenshots / Video demonstration keyboard-stuck-result

Screen recording in the sample repository:

https://github.com/hoyahozz/ios-keyboard-stuck-after-app-switch/blob/main/media/keyboard-stuck-result.mov

Logs

Logs

Latest Flutter 3.44.5 stable log excerpt:

flutter: 10:43:48.948 lifecycle=AppLifecycleState.inactive
flutter: 10:43:48.948 focus after lifecycle change: primaryFocus=first_text_field; textFieldFocus=first=true, second=false, multiline=false
flutter: 10:43:48.949 metrics after lifecycle change: viewInsets.bottom=physical=924.0, logical=308.0
flutter: 10:43:49.668 metrics changed: viewInsets.bottom=physical=924.0, logical=308.0
flutter: 10:43:49.675 primary focus changed: primaryFocus=_ModalScopeState<dynamic> Focus Scope; textFieldFocus=first=false, second=false, multiline=false
flutter: 10:43:49.767 lifecycle=AppLifecycleState.hidden
flutter: 10:43:49.768 focus after lifecycle change: primaryFocus=_ModalScopeState<dynamic> Focus Scope; textFieldFocus=first=false, second=false, multiline=false
flutter: 10:43:49.768 metrics after lifecycle change: viewInsets.bottom=physical=924.0, logical=308.0
flutter: 10:43:49.769 lifecycle=AppLifecycleState.paused
flutter: 10:43:49.769 focus after lifecycle change: primaryFocus=_ModalScopeState<dynamic> Focus Scope; textFieldFocus=first=false, second=false, multiline=false
flutter: 10:43:49.769 metrics after lifecycle change: viewInsets.bottom=physical=924.0, logical=308.0
flutter: 10:43:49.907 metrics changed: viewInsets.bottom=physical=0.0, logical=0.0
flutter: 10:43:50.577 lifecycle=AppLifecycleState.hidden
flutter: 10:43:50.577 focus after lifecycle change: primaryFocus=_ModalScopeState<dynamic> Focus Scope; textFieldFocus=first=false, second=false, multiline=false
flutter: 10:43:50.578 metrics after lifecycle change: viewInsets.bottom=physical=0.0, logical=0.0
flutter: 10:43:50.578 lifecycle=AppLifecycleState.inactive
flutter: 10:43:50.578 focus after lifecycle change: primaryFocus=_ModalScopeState<dynamic> Focus Scope; textFieldFocus=first=false, second=false, multiline=false
flutter: 10:43:50.579 metrics after lifecycle change: viewInsets.bottom=physical=0.0, logical=0.0
flutter: 10:43:50.592 metrics changed: viewInsets.bottom=physical=0.0, logical=0.0
flutter: 10:43:50.615 lifecycle=AppLifecycleState.resumed
flutter: 10:43:50.616 focus after lifecycle change: primaryFocus=_ModalScopeState<dynamic> Focus Scope; textFieldFocus=first=false, second=false, multiline=false
flutter: 10:43:50.616 metrics after lifecycle change: viewInsets.bottom=physical=0.0, logical=0.0
flutter: 10:43:51.003 metrics changed: viewInsets.bottom=physical=0.0, logical=0.0
flutter: 10:43:51.006 metrics changed: viewInsets.bottom=physical=117.7, logical=39.2
flutter: 10:43:51.312 metrics changed: viewInsets.bottom=physical=920.6, logical=306.9
flutter: 10:43:51.323 metrics changed: viewInsets.bottom=physical=921.4, logical=307.1
flutter: 10:43:51.730 metrics changed: viewInsets.bottom=physical=924.0, logical=308.0
flutter: 10:43:51.730 metrics changed: viewInsets.bottom=physical=924.0, logical=308.0
flutter: 10:43:51.735 metrics changed: viewInsets.bottom=physical=924.0, logical=308.0

I also reproduced it with a multiline TextField:

flutter: 10:44:15.640 primary focus changed: primaryFocus=multiline_text_field; textFieldFocus=first=false, second=false, multiline=true
flutter: 10:44:17.049 lifecycle=AppLifecycleState.inactive
flutter: 10:44:17.050 focus after lifecycle change: primaryFocus=multiline_text_field; textFieldFocus=first=false, second=false, multiline=true
flutter: 10:44:17.050 metrics after lifecycle change: viewInsets.bottom=physical=924.0, logical=308.0
flutter: 10:44:17.772 primary focus changed: primaryFocus=_ModalScopeState<dynamic> Focus Scope; textFieldFocus=first=false, second=false, multiline=false
flutter: 10:44:18.491 lifecycle=AppLifecycleState.resumed
flutter: 10:44:18.491 focus after lifecycle change: primaryFocus=_ModalScopeState<dynamic> Focus Scope; textFieldFocus=first=false, second=false, multiline=false
flutter: 10:44:18.491 metrics after lifecycle change: viewInsets.bottom=physical=0.0, logical=0.0
flutter: 10:44:18.580 metrics changed: viewInsets.bottom=physical=199.2, logical=66.4
flutter: 10:44:18.912 metrics changed: viewInsets.bottom=physical=923.1, logical=307.7
flutter: 10:44:19.244 metrics changed: viewInsets.bottom=physical=924.0, logical=308.0

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.44.5, on macOS 26.5.1 25F80 darwin-arm64, locale ko-KR)
    • Flutter version 3.44.5 on channel stable at <flutter-sdk-path>
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision f94f4fc76b, 2026-07-06 11:19:24 -0700
    • Engine revision 83675ed276
    • Dart version 3.12.2
    • DevTools version 2.57.0
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets, enable-swift-package-manager, omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration

[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
    • Android SDK at <redacted>
    • Emulator version 36.1.9.0 (build_id 13823996) (CL:N/A)
    • Platform android-36, build-tools 35.0.0
    • Java binary at: /Applications/Android Studio Narwhal 3 Feature Drop 2025.1.3.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 21.0.7+-13880790-b1038.58)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 26.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 17C52
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web

[✓] Connected device
    • iPhone 17 (mobile)     • <redacted>      • ios            • iOS 26.5.1 23F81
    • iPhone 15 Pro          • <simulator-id>  • ios            • iOS 17.5 simulator
    • macOS                  • macos           • darwin-arm64   • macOS 26.5.1 25F80 darwin-arm64
    • Chrome                 • chrome          • web-javascript

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Activity

  1. saurabh-mirajkar commented on Jul 7, 2026

    @saurabh-mirajkar
    Contributor

    @hoyahozz Thanks for the detailed report. I notice you are currently using Flutter v3.35.1, which is quite old at this point. Could you please verify if this issue still persists on the latest stable release (v3.44.5)?

  2. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    and removed
    in triagePresently being triaged by the triage team
    on Jul 7, 2026
  3. hoyahozz commented on Jul 8, 2026

    @hoyahozz
    ContributorAuthor

    @saurabh-mirajkar

    Thanks for checking. I re-tested this on Flutter 3.44.5 stable, and the issue still occurs intermittently.

    Environment:

    • Flutter 3.44.5 stable
    • Dart 3.12.2
    • Xcode 26.2
    • Physical iPhone 17, iOS 26.5.1

    It does not happen on every app switch, but I can reproduce it by repeating the same quick app switch sequence. When it happens, no sample TextField has focus after returning to the app, but viewInsets.bottom grows back to the keyboard height.

    I also updated the sample repository README with the Flutter 3.44.5 verification result and flutter doctor -v output:
    https://github.com/hoyahozz/ios-keyboard-stuck-after-app-switch

  4. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Jul 8, 2026
  5. puneetkukreja98 commented on Jul 8, 2026

    @puneetkukreja98
    Contributor

    @hoyahozz Thanks for the response.

    I tried reproducing the issue, but I wasn't able to reproduce it on the following devices:

    1. iPhone 13 (Physical device, iOS 18)
    2. iPhone 17 Simulator (iOS 26.5)

    It might be specific to the latest iOS version and only reproducible on a physical device.

    Findings

    I wasn't able to reproduce the issue.

    Video

    iPhone-17-sim-ios-26.5.mov
    iPhone-13-ios-18.0.1.mp4

    Flutter doctor -v:

    [✓] Flutter (Channel stable, 3.44.5, on macOS 26.4.1 25E253 darwin-arm64, locale
        en-US) [653ms]
        • Flutter version 3.44.5 on channel stable at
          /Users/puneetkukreja/Developer/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision f94f4fc76b (2 days ago), 2026-07-06 11:19:24 -0700
        • Engine revision 83675ed276
        • Dart version 3.12.2
        • DevTools version 2.57.0
        • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop,
          enable-windows-desktop, enable-android, enable-ios, cli-animations,
          enable-native-assets, no-enable-swift-package-manager,
          omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0)
        [2.7s]
        • Android SDK at /Users/puneetkukreja/Library/Android/sdk
        • Emulator version 36.5.10.0 (build_id 15081367) (CL:N/A)
        • Platform android-36.1, build-tools 36.1.0
        • Java binary at:
          /Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home/bin/java
          This JDK is specified in your Flutter configuration.
          To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
        • Java version Java(TM) SE Runtime Environment (build 17.0.12+8-LTS-286)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 26.6) [1,339ms]
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 17F113
        • CocoaPods version 1.16.2
    
    [✓] Chrome - develop for the web [5ms]
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Connected device (4 available) [7.3s]
        • Puneet’s iPhone (mobile) • 00008110-00167CEE0C46401E            • ios
          • iOS 18.0.1 22A3370
        • iPhone 17 (mobile)       • A4E176DE-CC21-4B11-B139-64F6A8172AC5 • ios
          • com.apple.CoreSimulator.SimRuntime.iOS-26-5 (simulator)
        • macOS (desktop)          • macos                                •
          darwin-arm64   • macOS 26.4.1 25E253 darwin-arm64
        • Chrome (web)             • chrome                               •
          web-javascript • Google Chrome 149.0.7827.199
    
    [✓] Network resources [1,078ms]
        • All expected network resources are available.
    
    • No issues found!
    
  6. puneetkukreja98 commented on Jul 8, 2026

    @puneetkukreja98
    Contributor

    Similar issues:
    #144463
    #178109
    #148117
    #150522

  7. added
    fyi-iosFor the attention of iOS platform team
    a: text inputEntering text in a text field or keyboard related problems
    platform-iosiOS applications specifically
    and removed
    in triagePresently being triaged by the triage team
    on Jul 8, 2026
  8. 8 remaining items

  9. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Aug 3, 2026
  10. LongCatIsLooong commented on Aug 3, 2026

    @LongCatIsLooong
    Contributor

    Not this - swipe up to the home screen, then tap the app icon to come back. This round trip does not reproduce it for me either.

    This - swipe horizontally along the home indicator to slide directly into the adjacent app, then immediately swipe back. iOS switches app-to-app without ever showing the home screen or the app switcher.

    Ah interesting thanks for the clarification. I'll try to repro this with the new instructions. From the description alone this feels like an iOS/UIKit bug to me since the callpath for switching between apps, and switching to the home screen and back should be the same for the app.

  11. cbracken commented on Aug 13, 2026

    @cbracken
    Member

    Something to look at: are we correctly firing the right KeyboardInsetManager updates on lifecycle notifications (background, return from background).

    Also worth checking while we're in there if we're also checking on:

    • App create (in case the text field is focused on startup) -- this wouldn't cause this issue
    • ViewController attach/detach (particularly for app extensions
  12. added
    P2Important issues not at the top of the work list
    team-iosOwned by iOS platform team
    fyi-text-inputFor the attention of Text Input team
    triaged-iosTriaged by iOS platform team
    and removed
    a: text inputEntering text in a text field or keyboard related problems
    fyi-iosFor the attention of iOS platform team
    on Aug 13, 2026
  13. github-actions commented on Oct 23, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  14. locked as resolved and limited conversation to collaborators on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

P2Important issues not at the top of the work listfyi-text-inputFor the attention of Text Input teamplatform-iosiOS applications specificallyteam-iosOwned by iOS platform teamtriaged-iosTriaged by iOS platform team

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions