Skip to content

VoiceOver occasionally doesn't announce typed characters/numbers in input fields #71885

Closed
flutter-team-archive/engine
#23776

Description

@mehmetf

b/174614592

This seems to reproduce with any text field.

  1. Turn on voiceover
  2. Type a few characters
  3. Delete a few back to back
  4. Without waiting for "delete" announcement to finish, type again

Sporadically, you will observe missed announcements for letters. See internal bug for a reproduction of the internal catalog app.

Activity

  1. self-assigned this
    on Dec 8, 2020
  2. chunhtai commented on Dec 8, 2020

    @chunhtai
    Contributor

    Flutter currently relying on voice over to pronounce focused soft keyboard key repeat user typing, and that seems to be buggy.

    The native ios App relies on some internal mechanism to pronounce the change in textfield. It does not seem to be public documented, I will keep digging.

  3. chunhtai commented on Dec 10, 2020

    @chunhtai
    Contributor

    I can't really tell how they decide to pronounce the character. I have asked a question in stackoverflow https://stackoverflow.com/questions/65225792/voiceover-does-not-repeat-typed-character-on-custom-text-view-with-uitextinput

    If we can't figure this out, we may be able to use UIAccessibilityAnnouncementNotification to force voice over to announce the typing.

  4. yama3nomori commented on Dec 30, 2020

    @yama3nomori

    I have the same question.
    I tried to add any properties of Textfield() and TextFormField().
    But VoiceOver cannot announce characters.

    When I tapped a edit box on iOS apps, VoiceOver usually focused the edit box.
    But it focus keyboard made by Flutter apps.
    I'm thinking at the curse.
    But I don't know how to solve it.

  5. Hixie commented on Jan 6, 2021

    @Hixie
    Contributor

    Update: We're not sure how to approach this; waiting for feedback from the customer.

  6. Hixie commented on Jan 13, 2021

    @Hixie
    Contributor

    @pcsosinski says he will reach out to the customer next week.

  7. yasargil commented on Jan 19, 2021

    @yasargil

    We had an accessibility review of our prototype app written with flutter (Engine ref 4797b06) and this bug came up. Except that voiceover never announced a single character typed. For user which rely on that feedback the keyboard is unusable in that state.

    Not much to find about his bug except this one:
    https://stackoverflow.com/questions/16270243/make-voiceover-announce-typed-deleted-characters-for-uikeyinput

    Edit i can't reproduce the problem in another app from us which was build with flutter 1.17(Not sure about that). engine revision for reference: ee76268252c22f5c11e82a7b87423ca3982e51a7

  8. chunhtai commented on Jan 19, 2021

    @chunhtai
    Contributor

    @yasargil thanks that is very helpful, I will look more into it

  9. chunhtai commented on Jan 19, 2021

    @chunhtai
    Contributor

    yes, I can confirm this is a regression, it works correctly before 1.17.0.

  10. 3 remaining items

  11. Hixie commented on Jan 26, 2021

    @Hixie
    Contributor

    @chunhtai Is it possible to prototype the solution you describe just enough to tell if it would work?

  12. chunhtai commented on Jan 27, 2021

    @chunhtai
    Contributor

    I prototyped it, it doesn't work. The soft keyboard only listens to UIView that implements UITextInput. The last suggestion makes UIAccessibilityElement to implement UITextInput, but the soft keyboard does not seem to respond to it.

    At this moment, I don't think there is a correct solution.

    The best we can have is

    (2) always switch the focus back to FlutterField as soon as the NativeField was focused.

    and makes NativeField harder to be reached.

  13. xster commented on Jan 27, 2021

    @xster
    Member

    Does moving the native field to the bottom right off-screen not work either?

  14. chunhtai commented on Jan 27, 2021

    @chunhtai
    Contributor

    no, it does not work, it still receives focus in this scenario

    Details
    import 'package:flutter/material.dart';
    import 'package:flutter_driver/flutter_driver.dart';
    import 'package:vm_service/vm_service.dart' as vms;
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Counter App',
          home: MyHomePage(title: 'Counter App Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
    
      void _incrementCounter() {
        Navigator.of(context).push(MaterialPageRoute(builder: (_)=>MyHomePage2(title: 'second',) ));
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: TextField(),
          ),
          floatingActionButton: FloatingActionButton(
            // Provide a Key to this button. This allows finding this
            // specific button inside the test suite, and tapping it.
            key: Key('increment'),
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }
    
    class MyHomePage2 extends StatefulWidget {
      MyHomePage2({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePage2State createState() => _MyHomePage2State();
    }
    
    class _MyHomePage2State extends State<MyHomePage2> {
      int _counter = 0;
    
      void _incrementCounter() {
        Navigator.of(context).push(MaterialPageRoute(builder: (_)=>MyHomePage(title: 'second',) ));
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: TextField(autofocus: true,),
          ),
          floatingActionButton: FloatingActionButton(
            // Provide a Key to this button. This allows finding this
            // specific button inside the test suite, and tapping it.
            key: Key('increment'),
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }
    
    class BackButtonListener extends StatefulWidget {
      final Widget child;
      final Future<bool> Function() onBackPressed;
    
      const BackButtonListener({
        this.child,
        this.onBackPressed,
      });
      @override
      BackButtonListenerState createState()=>BackButtonListenerState();
    }
    
    class BackButtonListenerState extends State<BackButtonListener> {
    
      BackButtonDispatcher dispatcher;
      @override
      void didChangeDependencies() {
        super.didChangeDependencies();
        if (dispatcher != null) {
          dispatcher.removeCallback(widget.onBackPressed);
        }
        dispatcher = Router.of(context)
            .backButtonDispatcher
            .createChildBackButtonDispatcher();
        dispatcher.addCallback(widget.onBackPressed);
        dispatcher.takePriority();
      }
    
      @override
      Widget build(BuildContext context) {
        return widget.child;
      }
    }
  15. MarcoZehe commented on Feb 4, 2021

    @MarcoZehe

    I am running into this set of problems as well. To me it feels as if the flutter field has the SupportsDirectInteraction trait set. With VoiceOver on, simply touching a text field makes the keyboard come up. Normally, this should only happen with a double tap once the text field has VoiceOver focus (the frame around it). Could that be part of the problem: The Flutter field swallowing gestures it should not?

  16. pcsosinski commented on Feb 18, 2021

    @pcsosinski

    this issue was present in 1.17 and 1.22 correct?

  17. chunhtai commented on Feb 18, 2021

    @chunhtai
    Contributor

    yes its a regression.

  18. pcsosinski commented on Feb 24, 2021

    @pcsosinski

    we're not planning to pick this into 1.26, the 1.27 beta release will be branching soon.

  19. github-actions commented on Aug 5, 2021

    @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.

  20. locked as resolved and limited conversation to collaborators on Aug 5, 2021
  21. added
    P0Critical issues such as a build break or regression
    and removed on Jun 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P0Critical issues such as a build break or regressiona: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)c: regressionIt was better in the past than it is nowcustomer: money (g3)platform-iosiOS applications specifically

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions