flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
166.34k stars 27.54k forks source link

[VoiceOver] Can not focus on TextField when inside sliver list that is scrolled. #52863

Open johnsonmh opened 4 years ago

johnsonmh commented 4 years ago

Internal: b/151285964

When a text field is in the body of a sliver list, and you scroll the sliver list under a sliver app bar, the text field is no longer editable through iOS VoiceOver.

Seems similar to https://github.com/flutter/flutter/issues/45394.

Steps to Reproduce

Using the following example app:

import 'package:flutter/material.dart';

void main() {
  runApp(Demo());
}

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: CustomScrollView(
          slivers: [
            SliverAppBar(
              pinned: true,
              expandedHeight: 200,
              flexibleSpace: Container(height: 100),
            ),
            SliverList(
              delegate: SliverChildListDelegate([
                Container(
                  height: 400,
                  child: Center(child: TextField()),
                ),
                Container(
                  height: 400,
                  child: Center(child: Text('empty box')),
                ),
              ]),
            ),
          ],
        ),
      ),
    );
  }
}
  1. Run the above app on an iOS device.
  2. Enable VoiceOver mode.
  3. Scroll the app down so that the SliverAppBar is collapsed.
  4. Attempt to edit the text field, notice that you can not focus on the text field, despite the VoiceOver saying "Text field, double tap to edit".

Also notice that if the app is not scrolled, the TextField is editable even with VoiceOver enabled.

Expected results: Text field can be focused on and text can be entered.

Actual results: Text field can not be focused on or edited.

Flutter doctor output ``` Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel fix-defaultTextStyleAboveMaterialApp, v1.15.12-pre.4, on Mac OS X 10.14.6 18G3020, locale en-US) [!] Android toolchain - develop for Android devices (Android SDK version 29.0.2) ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses [!] Xcode - develop for iOS and macOS (Xcode 11.3) ! CocoaPods 1.7.5 out of date (1.8.0 is recommended). CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side. Without CocoaPods, plugins will not work on iOS or macOS. For more info, see https://flutter.dev/platform-plugins To upgrade: sudo gem install cocoapods [✓] Chrome - develop for the web [✓] Android Studio (version 3.6) [✓] Android Studio (version 3.5) [✓] Connected device (5 available) ! Doctor found issues in 2 categories. ``` ``` ```
goderbauer commented 4 years ago

@johnsonmh I am not able to reproduce this. When I scroll all the way down, I can move a11y focus to the text field and when I double-tap it gets input focus and I can enter text.

When you say that you "cannot focus on the text field" - what do you mean by this? You can't give it a11y focus? Or you can't get it into a mode where it has input focus?

Also, what iOS device where you using?

johnsonmh commented 4 years ago

I'm using the iPhone XS, not the XS Max, but rather the smaller size (which could account for the difference).

And by "cannot focus on the text field", I mean when I navigate to the text field with voiceover, it says "Text Field, double tap to enter", but when I double tap, it does not bring the keyboard up.

Can you try it again on your device but make the second container ~1200 pixels tall instead of 400? I think it's important that the header fully collapse before the bug reproduces.

goderbauer commented 4 years ago

Thanks for the information. I can reproduce this now.

goderbauer commented 4 years ago

I looked at this briefly. When you double-tap while the textfield has a11y focus, that double tap is not forwarded to the flutter framework (window.onSemanticsAction does not fire), which is odd (This is true whether or not the textfield is scrolled up). Somehow, double-tapping on a textfield is completely handled in the engine's a11y bridge and it seems that the engine can only properly bring up the keyboard if the actual TextField is in the center of the semantics node.

This problem can actually easily be reproduced in much simpler settings without scrolling:

import 'package:flutter/material.dart';

void main() {
  runApp(Demo());
}

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Semantics(
          container: true,
          child: Container(
            color: Colors.green,
            height: 500,
            child: Align(
              alignment: Alignment.bottomCenter,
              child: TextField(),
            ),
          ),
        ),
      ),
    );
  }
}

The problem occurs whenever the textfield is not in the center of the a11y-focused area.

goderbauer commented 4 years ago

I quick work-around is to wrap the textfield in a Semantics container to make sure that the semantics node only has the size of the actual textfield:

                Container(
                  height: 400,
                  child: Center(
                    child: Semantics(
                      container: true,
                      child: TextField(),
                    ),
                  ),
                ),

@johnsonmh Is this enough to unblock the customer? Or is fixing this still customer critical?

goderbauer commented 4 years ago

/cc @xster FYI since the actual problem seems to be in the iOS accessibility bridge.

goderbauer commented 4 years ago

There's still an issue here: If you have an accessibility node with a text field inside you cannot input-focus it if the textfield is not in the center of the node, see https://github.com/flutter/flutter/issues/52863#issuecomment-604159185.

TahaTesser commented 4 years ago

I can focus on texiifeld after scrolll

flutter doctor -v ``` [✓] Flutter (Channel dev, 1.20.0-7.1.pre, on Mac OS X 10.15.6 19G73, locale en-GB) • Flutter version 1.20.0-7.1.pre at /Users/taha/Code/flutter_dev • Framework revision 7736f3bc90 (6 days ago), 2020-07-10 16:33:05 -0700 • Engine revision d48085141c • Dart version 2.9.0 (build 2.9.0-21.2.beta) [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.0) • Android SDK at /Users/taha/Code/sdk • Platform android-30, build-tools 30.0.0 • ANDROID_HOME = /Users/taha/Code/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 11.6) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 11.6, Build version 11E708 • CocoaPods version 1.9.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 4.0) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin version 47.1.2 • Dart plugin version 193.7361 • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) [✓] VS Code (version 1.47.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.12.2 [✓] Connected device (5 available) • SM M305F (mobile) • 32003c30dc19668f • android-arm64 • Android 10 (API 29) • Taha’s iPhone (mobile) • 00008020-001059882212002E • ios • iOS 13.6 • macOS (desktop) • macos • darwin-x64 • Mac OS X 10.15.6 19G73 • Web Server (web) • web-server • web-javascript • Flutter Tools • Chrome (web) • chrome • web-javascript • Google Chrome 83.0.4103.116 • No issues found! ```

Adding passed first triage based on https://github.com/flutter/flutter/issues/52863#issuecomment-613726989