Repository: flutter
Issue: [iOS]Accessibility semantic vertical swipe gesture doesn't work although container = true?
Labels: platform-ios,framework,a: accessibility,has reproducible steps,P2,found in release: 3.7,found in release: 3.10,team-ios,triaged-ios

Hello,

1. I am having problems to understand how the container parameter in the Semantics widget should work while VoiceOver is active. Despite setting the container parameter true, a vertical swipe doesn't result in jumping to the next widget which is set as container = true. Does anyone know how to achieve this or is this a bug?

2. Is it possible to assign the AppBar widget a semantic container? (or shouldn't be this default?)

<details>
  <summary>flutter doctor -v</summary>
  
`[!] Flutter (Channel stable, 3.7.10, on macOS 12.6 21G115 darwin-arm64, locale languagecode-countrycode)
    • Flutter version 3.7.10 on channel stable at /Users/user/Desktop/Work/flutter
    ! Warning: `dart` on your path resolves to /opt/homebrew/Cellar/dart/2.18.2/libexec/bin/dart, which is not inside your current Flutter SDK checkout at
      /Users/user/Desktop/Work/flutter. Consider adding /Users/user/Desktop/Work/flutter/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4b12645012 (5 days ago), 2023-04-03 17:46:48 -0700
    • Engine revision ec975089ac
    • Dart version 2.19.6
    • DevTools version 2.20.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 32.1.0-rc1)
    • Android SDK at /Users/user/Library/Android/sdk
    • Platform android-33, build-tools 32.1.0-rc1
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7772763)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14C18
    • CocoaPods version 1.11.3

[✓] Android Studio (version 2021.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 11.0.11+0-b60-7772763)

[✓] IntelliJ IDEA Ultimate Edition (version 2021.3.3)
    • IntelliJ at /Applications/IntelliJ IDEA.app
    • 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

[✓] Connected device (2 available)
    • iPhone 14 Pro Max (mobile) • 17592BB3-C10C-4AF3-B3B1-6C9A2092D68D • ios          • com.apple.CoreSimulator.SimRuntime.iOS-16-2 (simulator)
    • macOS (desktop)            • macos                                • darwin-arm64 • macOS 12.6 21G115 darwin-arm64

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 1 category.`

</details>

Tab Push is referring to issue: https://github.com/flutter/flutter/issues/123998

Tab Container is referring to this issue.

<details>
  <summary>code sample</summary>

```dart
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: 'Semantic Test App',
      //home: MyStatefulWidget(),
      initialRoute: '/',
      routes: {
        '/': (context) => const MyStatefulWidget(),
        '/second': (context) => const PageTest(),
      },
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({super.key});

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Semantic Code Sample'),
      ),
      body: Center(
        child: [
          const TabPush(),
          const TabContainer(),
        ].elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.arrow_back_ios_outlined),
            label: 'Push',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.folder),
            label: 'Container',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.blue[800],
        onTap: (int index) {
          setState(() {
            _selectedIndex = index;
          });
        },
      ),
    );
  }
}

class PageTest extends StatelessWidget {
  const PageTest({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Pushed Page'),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 24),
          child: Semantics(
            header: true,
            child: const Text(
              'Z Gesture for dismiss doesn\'t work on pushed page',
              textAlign: TextAlign.center,
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
          ),
        ),
      ),
    );
  }
}

class TabPush extends StatelessWidget {
  const TabPush({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 24),
          child: Semantics(
              header: true,
              child: const Text(
                'Accessibility semantic escape gesture doesn\'t work with Navigator.push',
                textAlign: TextAlign.center,
                style: TextStyle(fontWeight: FontWeight.bold),
              )),
        ),
        const SizedBox(
          height: 24,
        ),
        TextButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const PageTest()),
              );
            },
            child: const Text('Navigator.push')),
        const SizedBox(
          height: 5,
        ),
        TextButton(
            onPressed: () {
              Navigator.pushNamed(context, '/second');
            },
            child: const Text('Navigator.pushNamed')),
        const SizedBox(
          height: 5,
        ),
        TextButton(
            onPressed: () {
              showModalBottomSheet<dynamic>(
                isScrollControlled: true,
                context: context,
                useRootNavigator: true,
                backgroundColor: Colors.transparent,
                builder: (context) => SizedBox(
                  height: 200,
                  child: Container(
                    color: Colors.blue,
                    child: const Center(
                        child: Text('Z Gesture for dismiss works in Panel')),
                  ),
                ),
              );
            },
            child: const Text('showModalBottomSheet')),
      ],
    );
  }
}

class TabContainer extends StatelessWidget {
  const TabContainer({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 24),
          child: Semantics(
              header: true,
              child: const Text(
                'Semantic parameter container=true vertical swipe gesture doesn\'t work correctly?',
                textAlign: TextAlign.center,
                style: TextStyle(fontWeight: FontWeight.bold),
              )),
        ),
        const SizedBox(
          height: 24,
        ),
        Semantics(
          label: 'Container 1',
          container: true,
          explicitChildNodes: true,
          child: Column(
            children: const [
              Text('Container 1 Item 1'),
              Text('Container 1 Item 2'),
              Text('Container 1 Item 3'),
            ],
          ),
        ),
        const SizedBox(
          height: 24,
        ),
        Semantics(
          label: 'Container 2',
          container: true,
          explicitChildNodes: true,
          child: Column(
            children: const [
              Text('Container 2 Item 1'),
              Text('Container 2 Item 2'),
              Text('Container 2 Item 3'),
            ],
          ),
        ),
        const SizedBox(
          height: 24,
        ),
        Semantics(
          label: 'Container 3',
          container: true,
          explicitChildNodes: true,
          child: Column(
            children: const [
              Text('Container 3 Item 1'),
              Text('Container 3 Item 2'),
              Text('Container 3 Item 3'),
            ],
          ),
        )
      ],
    );
  }
}
```

</details>