Skip to content

VoiceOver [iOS] no longer respects scopesRoute and namesRoute in Flutter 1.22 #67345

@dannyvalentesonos

Description

@dannyvalentesonos

In Flutter 1.19, the behavior with the code below is that VoiceOver would successfully read "Page 1 -> Hello, press the button below to launch the next page".

Selecting and double tapping on "Launch route 2" would result in VoiceOver reading "Page 2 -> Hello, press the button below to close this page".

Going back and forth between page routes would work nicely, and the first element on the page would always be selected and read.

However, in Flutter 1.22, that's no longer the case. The semantics label is random whether it's read, and the first element on the page is also random to whether it gets selected or not.

This breaks our experience for visually impaired uses in our app.

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SemanticsNav1HomePage(),
    );
  }
}

class SemanticsNav1HomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);

    return Semantics(
      scopesRoute: true,
      namesRoute: true,
      label: "Page 1",
      explicitChildNodes: true,
      child: Scaffold(
        body: SafeArea(
          top: true,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            mainAxisSize: MainAxisSize.max,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.all(24.0),
                child: Text(
                  "Hello, press the button below to launch the next page",
                  style: TextStyle(fontSize: 24),
                ),
              ),
              Expanded(
                child: Center(
                  child: MaterialButton(
                      color: Colors.black,
                      textColor: Colors.white,
                      child: Text("Launch route 2", style: TextStyle(fontSize: 20)),
                      onPressed: () => Navigator.push(context, PageRouteBuilder(pageBuilder: (context, animation, secondaryAnimation) => SemanticsNav2HomePage())),
                  )
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class SemanticsNav2HomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);

    return Semantics(
      scopesRoute: true,
      namesRoute: true,
      label: "Page 2",
      explicitChildNodes: true,
      child: Scaffold(
        body: SafeArea(
          top: true,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            mainAxisSize: MainAxisSize.max,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.all(24.0),
                child: Text(
                  "Hello, press the button below to close this page",
                  style: TextStyle(fontSize: 24),
                ),
              ),
              Expanded(
                child: Center(
                    child: MaterialButton(
                      color: Colors.black,
                      textColor: Colors.white,
                      child: Text("Pop route 2", style: TextStyle(fontSize: 20)),
                        onPressed: () => Navigator.pop(context),
                    )
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
Flutter doctor

[✓] Flutter (Channel beta, 1.22.0-12.2.pre, on Mac OS X 10.15.6 19G2021, locale en-US)
• Flutter version 1.22.0-12.2.pre at /Users/danny.valente/Library/flutter/1.22.0-12.2.pre-beta
• Framework revision 2bafdc8 (10 days ago), 2020-09-25 12:48:22 -0700
• Engine revision f763b5b
• Dart version 2.10.0 (build 2.10.0-110.5.beta)

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
• Android SDK at /Users/danny.valente/Library/Android/sdk
• Platform android-29, build-tools 29.0.2
• 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.4.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 11.4.1, Build version 11E503a
• CocoaPods version 1.9.3

[✓] 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)

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 nowengineflutter/engine related. See also e: labels.found in release: 1.23Found to occur in 1.23has reproducible stepsThe issue has been confirmed reproducible and is ready to work on

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions