flutter icon indicating copy to clipboard operation
flutter copied to clipboard

[iOS] Keyboard loses focus after Look Up text selection

Open starikovvm opened this issue 1 year ago • 4 comments
trafficstars

Steps to reproduce

App is launched on iOS 17.2 (reproduces both on a simulator and on a real device)

  1. Select text in Text Field
  2. Press Look up
  3. Close the Look up dialog

Expected results

Keyboard hides or text field returns its focus

Actual results

Keyboard persists on screen, but the text field does not retain focus and keyboard does not hide via unfocus() (see video)

Code sample

Code sample
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const TextField(),
            TextButton(
              onPressed: () => FocusScope.of(context).unfocus(),
              child: const Text('FocusScope.of(context).unfocus()'),
            ),
            TextButton(
              onPressed: () => FocusManager.instance.primaryFocus?.unfocus(),
              child:
                  const Text('FocusManager.instance.primaryFocus?.unfocus()'),
            ),
          ],
        ),
      ),
    );
  }
}


Screenshots or Video

Screenshots / Video demonstration

https://github.com/flutter/flutter/assets/6888015/d2470686-152c-4f3b-8476-66763d7a7932

Logs

Logs
no logs

Flutter Doctor output

Doctor output
[flutter] flutter doctor -v
[!] Flutter (Channel stable, 3.19.2, on macOS 14.3.1 23D60 darwin-arm64, locale ru-RU)
    • Flutter version 3.19.2 on channel stable at /Users/viktorstarikov/fvm/versions/3.19.2
    ! Warning: `flutter` on your path resolves to /Users/viktorstarikov/fvm/versions/3.10.4/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/viktorstarikov/fvm/versions/3.19.2. Consider adding /Users/viktorstarikov/fvm/versions/3.19.2/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /opt/homebrew/Cellar/dart/3.0.1/libexec/bin/dart, which is not inside your current Flutter SDK checkout at /Users/viktorstarikov/fvm/versions/3.19.2. Consider adding /Users/viktorstarikov/fvm/versions/3.19.2/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 7482962148 (2 days ago), 2024-02-27 16:51:22 -0500
    • Engine revision 04817c99c9
    • Dart version 3.3.0
    • DevTools version 2.31.1
    • 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 33.0.2)
    • Android SDK at /Users/viktorstarikov/Library/Android/sdk
    • Platform android-33, build-tools 33.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
    • Xcode at /Applications/Xcode-15.2.0.app/Contents/Developer
    • Build 15C500b
    • CocoaPods version 1.13.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.1)
    • 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
    • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)

[✓] VS Code (version 1.86.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.82.0

[✓] Connected device (5 available)
    • sdk gphone64 arm64 (mobile) • emulator-5554                        • android-arm64  • Android 13 (API 33) (emulator)
    • iPhone 6s Plus (mobile)     • 00008110-000A388A3AF9801E            • ios            • iOS 17.2.1 21C66
    • iPhone 15 Pro Max (mobile)  • 97CAF3A4-246E-462F-968B-A414DE0A3445 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-17-2 (simulator)
    • macOS (desktop)             • macos                                • darwin-arm64   • macOS 14.3.1 23D60 darwin-arm64
    • Chrome (web)                • chrome                               • web-javascript • Google Chrome 122.0.6261.94
    ! Error: Browsing on the local area network for Apple Watch — Viktor. Ensure the device is unlocked and discoverable via Bluetooth. (code -27)

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

! Doctor found issues in 1 category.

starikovvm avatar Mar 01 '24 07:03 starikovvm

Reproducible using the code sample provided above.

With the native iOS notes and reminders app, the behaviours are different. Notes dismisses the keyboard whereas reminders refocuses the keyboard. See the recordings below

It looks like the lookUpSelection method in the framework doesn't handle anything else after calling the method to invoke the look up window.

https://github.com/flutter/flutter/blob/e8f8a8dc17054425abda5f77d3e714a2668f08fe/packages/flutter/lib/src/widgets/editable_text.dart#L2598-L2609

flutter notes reminder
flutter doctor -v
[✓] Flutter (Channel stable, 3.19.2, on macOS 14.3.1 23D60 darwin-arm64, locale en-GB)
    • Flutter version 3.19.2 on channel stable at /Users/nexus/dev/sdks/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 7482962148 (3 days ago), 2024-02-27 16:51:22 -0500
    • Engine revision 04817c99c9
    • Dart version 3.3.0
    • DevTools version 2.31.1

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Users/nexus/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
    • Xcode at /Applications/Xcode-15.2.0.app/Contents/Developer
    • Build 15C500b
    • CocoaPods version 1.14.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.1)
    • Android Studio at /Users/nexus/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
    • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.2.5)
    • IntelliJ at /Users/nexus/Applications/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 77.2.2
    • Dart plugin version 232.10286

[✓] VS Code (version 1.86.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.82.0

[✓] Connected device (4 available)
    • Nexus (mobile)       • 00008020-001875E83A38002E • ios            • iOS 17.3.1 21D61
    • Dean’s iPad (mobile) • 00008103-000825C811E3401E • ios            • iOS 17.3.1 21D61
    • macOS (desktop)      • macos                     • darwin-arm64   • macOS 14.3.1 23D60 darwin-arm64
    • Chrome (web)         • chrome                    • web-javascript • Google Chrome 122.0.6261.69

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

• No issues found!
[!] Flutter (Channel master, 3.20.0-16.0.pre.43, on macOS 14.3.1 23D60 darwin-arm64, locale en-GB)
    • Flutter version 3.20.0-16.0.pre.43 on channel master at /Users/nexus/dev/sdks/flutters
    ! Warning: `flutter` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ab10e2b1dd (5 hours ago), 2024-03-01 00:21:09 -0500
    • Engine revision f68cc57cbe
    • Dart version 3.4.0 (build 3.4.0-190.0.dev)
    • DevTools version 2.33.1
    • 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/nexus/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Users/nexus/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
    • Xcode at /Applications/Xcode-15.2.0.app/Contents/Developer
    • Build 15C500b
    • CocoaPods version 1.14.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.1)
    • Android Studio at /Users/nexus/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
    • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.2.5)
    • IntelliJ at /Users/nexus/Applications/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 77.2.2
    • Dart plugin version 232.10286

[✓] VS Code (version 1.86.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.82.0

[✓] Connected device (5 available)
    • Nexus (mobile)                  • 00008020-001875E83A38002E • ios            • iOS 17.3.1 21D61
    • Dean’s iPad (mobile)            • 00008103-000825C811E3401E • ios            • iOS 17.3.1 21D61
    • macOS (desktop)                 • macos                     • darwin-arm64   • macOS 14.3.1 23D60 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad     • darwin         • macOS 14.3.1 23D60 darwin-arm64
    • Chrome (web)                    • chrome                    • web-javascript • Google Chrome 122.0.6261.69

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

! Doctor found issues in 1 category.

danagbemava-nc avatar Mar 01 '24 10:03 danagbemava-nc

can take a look if it's possible to track what was on focus before presenting the lookup window, and then regain the focus after look up window is dismissed (not sure if there's a delegate callback we can use when look up window is dismissed)

cc @LouiseHsu

hellohuanlin avatar Mar 05 '24 21:03 hellohuanlin

I think this is actually a regression. I looked up my demo from when I initially merged the look up feature and it stayed highlighted. Will look into this more.

https://github.com/flutter/flutter/assets/36148254/8b9d9a1e-c39c-4d07-8572-b892cc439a84

LouiseHsu avatar Mar 06 '24 22:03 LouiseHsu

This issue is assigned to @LouiseHsu but has had no recent status updates. Please consider unassigning this issue if it is not going to be addressed in the near future. This allows people to have a clearer picture of what work is actually planned. Thanks!

flutter-triage-bot[bot] avatar Jul 11 '24 01:07 flutter-triage-bot[bot]

Same issue occurs when using image_picker and it results in an error:

https://github.com/user-attachments/assets/5da3ad91-5b00-4a9d-bb0c-abb38bb5cec8

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:keyboard_detection/keyboard_detection.dart';

void main() {
  runApp(const MainApp());
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  @override
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  late FocusNode specialFocusNode;
  late KeyboardDetectionController keyboardDetectionController;

  @override
  void initState() {
    super.initState();
    specialFocusNode = FocusNode();

    keyboardDetectionController = KeyboardDetectionController();
  }

  @override
  void dispose() {
    specialFocusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: KeyboardDetection(
        controller: keyboardDetectionController,
        child: GestureDetector(
          onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
          child: Scaffold(
            body: StreamBuilder(
                stream: keyboardDetectionController.stream,
                builder: (context, snapshot) {
                  return Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(snapshot.data.toString()),
                      const TextField(),
                      Flexible(
                        child: ElevatedButton(
                            onPressed: () async {
                              final ImagePicker picker = ImagePicker();

                              await picker.pickImage(source: ImageSource.camera);
                            },
                            child: const Text('Pick Image')),
                      ),
                      ElevatedButton(
                          onPressed: () {
                            FocusScope.of(context).requestFocus(specialFocusNode);
                          },
                          child: const Text('Request Focus Again By TextField FocusNode')),
                      ElevatedButton(
                          onPressed: () {
                            Navigator.push(
                              context,
                              MaterialPageRoute(
                                  builder: (context) => Scaffold(
                                        appBar: AppBar(),
                                        body: const Center(
                                          child: Text("Next Page"),
                                        ),
                                      )),
                            );
                          },
                          child: const Text('Go Next page')),
                      ElevatedButton(
                          onPressed: () {
                            specialFocusNode.unfocus();
                          },
                          child: const Text('Remove Focus By TextField FocusNode')),
                      ElevatedButton(
                          onPressed: () {
                            FocusScope.of(context).unfocus();
                          },
                          child: const Text('Remove Focus By FocusScope ')),
                    ],
                  );
                }),
          ),
        ),
      ),
    );
  }
}

AhmedLSayed9 avatar Jul 17 '24 18:07 AhmedLSayed9

This issue was assigned to @LouiseHsu but has had no status updates in a long time. To remove any ambiguity about whether the issue is being worked on, the assignee was removed.

flutter-triage-bot[bot] avatar Sep 29 '24 01:09 flutter-triage-bot[bot]

This issue is assigned to @LouiseHsu but has had no recent status updates. Please consider unassigning this issue if it is not going to be addressed in the near future. This allows people to have a clearer picture of what work is actually planned. Thanks!

flutter-triage-bot[bot] avatar Mar 20 '25 01:03 flutter-triage-bot[bot]

This issue was assigned to @LouiseHsu but has had no status updates in a long time. To remove any ambiguity about whether the issue is being worked on, the assignee was removed.

flutter-triage-bot[bot] avatar Jun 04 '25 22:06 flutter-triage-bot[bot]

@LouiseHsu Do you know if the issue was in the embedder or framework?

CC @LongCatIsLooong

justinmc avatar Jun 05 '25 20:06 justinmc

This is probably because the primary focus being resets to null in response to app lifecycle changes (https://github.com/flutter/flutter/pull/142930). I believe the behavior has been reverted on mobile (including on iOS: https://github.com/flutter/flutter/pull/148612)

The text field is still losing focus on master. I'll take a look and see what is happening.

LongCatIsLooong avatar Jun 05 '25 20:06 LongCatIsLooong

From triage: maybe this is related to shake to undo causing the TextField possibly to lose focus and not process the undo action https://github.com/flutter/flutter/issues/150522.

Renzo-Olivares avatar Aug 28 '25 20:08 Renzo-Olivares

From triage: maybe this is related to shake to undo causing the TextField possibly to lose focus and not process the undo action #150522.

The native text field must not close the input connection in these cases so it can receive undo commands even after losing focus.

LongCatIsLooong avatar Aug 28 '25 22:08 LongCatIsLooong