Thanks to visit codestin.com
Credit goes to github.com

Skip to content

CupertinoNavigationBarBackButton works incorrectly #89888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
fatadel opened this issue Sep 10, 2021 · 6 comments
Open

CupertinoNavigationBarBackButton works incorrectly #89888

fatadel opened this issue Sep 10, 2021 · 6 comments
Labels
f: cupertino flutter/packages/flutter/cupertino repository found in release: 2.5 Found to occur in 2.5 found in release: 2.6 Found to occur in 2.6 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on team-design Owned by Design Languages team

Comments

@fatadel
Copy link

fatadel commented Sep 10, 2021

Steps to Reproduce

  1. Run flutter create bug.
  2. Replace contents of main.dart file with the following:
import 'package:flutter/cupertino.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
      routes: {
        '/another-page': (context) => AnotherPage(),
      },
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: const Icon(CupertinoIcons.map),
            label: 'Page 1',
          ),
          BottomNavigationBarItem(
            icon: const Icon(CupertinoIcons.map),
            label: 'Page 2',
          ),
          BottomNavigationBarItem(
            icon: const Icon(CupertinoIcons.map),
            label: 'Page 3',
          ),
        ],
      ),
      tabBuilder: (context, i) {
        return CupertinoPageScaffold(
          navigationBar: CupertinoNavigationBar(
            middle: Text('Page $i'),
          ),
          child: SafeArea(
            child: Center(
              child: Container(
                width: double.infinity,
                height: 200,
                child: Column(
                  children: [
                    Text('Hello from Page $i!'),
                    CupertinoButton(
                      child: Text('Go to another page'),
                      onPressed: () =>
                          Navigator.of(context).pushNamed('/another-page'),
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}

class AnotherPage extends StatelessWidget {
  const AnotherPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    print(ModalRoute.of(context)!.canPop);

    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        leading: CupertinoNavigationBarBackButton(
          color: CupertinoColors.black,
        ),
        middle: Text('Another Page'),
      ),
      child: Center(
        child: Text('Hello from Another Page!'),
      ),
    );
  }
}

Run on iOS and click the button to go to Another Page.

Expected results: CupertinoNavigationBarBackButton works normally because the page where it's used indeed can pop.

Actual results: You will see the red box error on page transitions (back and forward) and the following message in the logs:

flutter: true

======== Exception caught by widgets library =======================================================
The following assertion was thrown building CupertinoNavigationBarBackButton(dirty):
CupertinoNavigationBarBackButton should only be used in routes that can be popped
'package:flutter/src/cupertino/nav_bar.dart':
Failed assertion: line 1312 pos 9: 'currentRoute?.canPop == true'


Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

The relevant error-causing widget was: 
  CupertinoNavigationBarBackButton file:///%PATH_TO_PROJECT%/lib/main.dart:81:18
When the exception was thrown, this was the stack: 
#2      CupertinoNavigationBarBackButton.build (package:flutter/src/cupertino/nav_bar.dart:1312:9)
#3      StatelessElement.build (package:flutter/src/widgets/framework.dart:4648:28)
#4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4574:15)
#5      Element.rebuild (package:flutter/src/widgets/framework.dart:4267:5)
#6      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4553:5)
...
====================================================================================================

  1. Output of flutter doctor:
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.2.3, on macOS 11.5.2 20G95 darwin-arm, locale ru-RU)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[!] Android Studio (version 2020.3)
    ✗ Unable to find bundled Java version.
[✓] VS Code (version 1.60.0)
[✓] Connected device (3 available)

! Doctor found issues in 1 category.
@danagbemava-nc danagbemava-nc added the in triage Presently being triaged by the triage team label Sep 13, 2021
@danagbemava-nc
Copy link
Member

Issue is reproducible on latest stable and master.

logs
Launching lib/issue_89888.dart on iPhone 12 in debug mode...
Xcode build done.                                           21.2s
Connecting to VM Service at ws://127.0.0.1:59263/87ly7mZFhcU=/ws
flutter: true

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building CupertinoNavigationBarBackButton(dirty):
CupertinoNavigationBarBackButton should only be used in routes that can be popped
'package:flutter/src/cupertino/nav_bar.dart':
Failed assertion: line 1336 pos 9: 'currentRoute?.canPop == true'


Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

The relevant error-causing widget was
CupertinoNavigationBarBackButton CupertinoNavigationBarBackButton:file:///Users/nexus/projects/nevercode/w6/lib/issue_89888.dart:80:18
When the exception was thrown, this was the stack
#2      CupertinoNavigationBarBackButton.build
#3      StatelessElement.build
#4      ComponentElement.performRebuild
#5      Element.rebuild
#6      ComponentElement._firstBuild
#7      ComponentElement.mount
...     Normal element mounting (25 frames)
#32     Element.inflateWidget
#33     MultiChildRenderObjectElement.inflateWidget
#34     MultiChildRenderObjectElement.mount
...     Normal element mounting (53 frames)
#87     Element.inflateWidget
#88     MultiChildRenderObjectElement.inflateWidget
#89     Element.updateChild
#90     RenderObjectElement.updateChildren
#91     MultiChildRenderObjectElement.update
#92     Element.updateChild
#93     ComponentElement.performRebuild
#94     StatefulElement.performRebuild
#95     Element.rebuild
#96     BuildOwner.buildScope
#97     WidgetsBinding.drawFrame
#98     RendererBinding._handlePersistentFrameCallback
#99     SchedulerBinding._invokeFrameCallback
#100    SchedulerBinding.handleDrawFrame
#101    SchedulerBinding._handleDrawFrame
#105    _invoke (dart:ui/hooks.dart:166:10)
#106    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:270:5)
#107    _drawFrame (dart:ui/hooks.dart:129:31)
(elided 5 frames from class _AssertionError and dart:async)
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
CupertinoNavigationBarBackButton should only be used in routes that can be popped
'package:flutter/src/cupertino/nav_bar.dart':
Failed assertion: line 1336 pos 9: 'currentRoute?.canPop == true'

The relevant error-causing widget was
CupertinoNavigationBarBackButton CupertinoNavigationBarBackButton:file:///Users/nexus/projects/nevercode/w6/lib/issue_89888.dart:80:18
════════════════════════════════════════════════════════════════════════════════
Application finished.
Exited (sigterm)
flutter doctor -v
[✓] Flutter (Channel master, 2.6.0-1.0.pre.256, on macOS 11.5.1 20G80 darwin-arm, locale en-GB)
    • Flutter version 2.6.0-1.0.pre.256 at /Users/nexus/dev/sdks/flutters
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 0d0f7a4fb0 (10 hours ago), 2021-09-12 21:17:23 -0700
    • Engine revision abb1980f65
    • Dart version 2.15.0 (build 2.15.0-96.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-31, build-tools 31.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.5.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • CocoaPods version 1.11.0

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

[✓] Android Studio (version 2020.3)
    • 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.10+0-b96-7249189)

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

[✓] Connected device (4 available)
    • Nexus’ IPhone (mobile) • 00008020-001875E83A38002E            • ios            • iOS 14.7.1 18G82
    • iPhone 12 (mobile)     • F2592D43-5FE3-46BB-8A2B-A38BA468DCE9 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-5 (simulator)
    • macOS (desktop)        • macos                                • darwin-arm64   • macOS 11.5.1 20G80 darwin-arm
    • Chrome (web)           • chrome                               • web-javascript • Google Chrome 93.0.4577.63

• No issues found!
[✓] Flutter (Channel stable, 2.5.0, on macOS 11.5.1 20G80 darwin-arm, locale en-GB)
    • Flutter version 2.5.0 at /Users/nexus/dev/sdks/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4cc385b4b8 (5 days ago), 2021-09-07 23:01:49 -0700
    • Engine revision f0826da7ef
    • Dart version 2.14.0

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-31, build-tools 31.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.5.1, Build version 12E507
    • CocoaPods version 1.11.0

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

[✓] Android Studio (version 2020.3)
    • 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.10+0-b96-7249189)

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

[✓] Connected device (4 available)
    • Nexus’ IPhone (mobile) • 00008020-001875E83A38002E            • ios            • iOS 14.7.1 18G82
    • iPhone 12 (mobile)     • F2592D43-5FE3-46BB-8A2B-A38BA468DCE9 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-5 (simulator)
    • macOS (desktop)        • macos                                • darwin-arm64   • macOS 11.5.1 20G80 darwin-arm
    • Chrome (web)           • chrome                               • web-javascript • Google Chrome 93.0.4577.63

• No issues found!

@danagbemava-nc danagbemava-nc added f: cupertino flutter/packages/flutter/cupertino repository found in release: 2.5 Found to occur in 2.5 found in release: 2.6 Found to occur in 2.6 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on and removed in triage Presently being triaged by the triage team labels Sep 13, 2021
@TahaTesser
Copy link
Member

TahaTesser commented Oct 4, 2021

Used the following minimal code sample

complete minimal runnable code sample
import 'package:flutter/cupertino.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      title: 'Cupertino App',
      home: Home(),
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('Cupertino App Bar'),
      ),
      child: Center(
        child: CupertinoButton(
          child: Text('Go to second'),
          onPressed: () => Navigator.of(context).push(
            CupertinoPageRoute(
              builder: (context) => AnotherPage(),
            ),
          ),
        ),
      ),
    );
  }
}

class AnotherPage extends StatelessWidget {
  const AnotherPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // final ModalRoute<dynamic>? currentRoute = ModalRoute.of(context);
    // print('canPop? - ${currentRoute?.canPop}');

    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        leading: CupertinoNavigationBarBackButton(
          color: CupertinoColors.black,
          onPressed: () {},
        ),
        middle: Text('Another Page'),
      ),
      child: Center(
        child: CupertinoButton(
          child: Text('Press me'),
          onPressed: () {
            print(ModalRoute.of(context)!.canPop);
          },
        ),
      ),
    );
  }
}

I just dug deeper into this, the main exception is thrown because when implementing CupertinoNavigationBarBackButton because currentRoute?.canPop is temporarily returned null during the transition with CupertinoNavigationBarBackButton

main.dart

      navigationBar: CupertinoNavigationBar(
        leading: CupertinoNavigationBarBackButton(
          color: CupertinoColors.black,
          onPressed: () {},
        ),
        middle: Text('Another Page'),
      ),

nav_bar.dart

  Widget build(BuildContext context) {
    final ModalRoute<dynamic>? currentRoute = ModalRoute.of(context);
    print(
        'CupertinoNavigationBarBackButton.build.canPop? - ${currentRoute?.canPop}');
    if (onPressed == null) {
      assert(
        currentRoute?.canPop == true,
        'CupertinoNavigationBarBackButton should only be used in routes that can be popped',
      );
    }

Initially currentRoute?.canPop it returns true > null > true again

Logs

flutter: CupertinoNavigationBarBackButton.build.canPop? - true
flutter: CupertinoNavigationBarBackButton.build.canPop? - null
flutter: CupertinoNavigationBarBackButton.build.canPop? - true

Now try commenting CupertinoNavigationBarBackButton, currentRoute?.canPopdoesn't go null anymore

main.dart

        // leading: CupertinoNavigationBarBackButton(
        //   color: CupertinoColors.black,
        //   onPressed: () {},
        // ),

Logs

flutter: CupertinoNavigationBarBackButton.build.canPop? - true
flutter: CupertinoNavigationBarBackButton.build.canPop? - true
flutter: CupertinoNavigationBarBackButton.build.canPop? - true

CC: @chunhtai
I see that you've worked on improving canPop logic in this PR #73993 which also includes a test for CupertinoNavigationBarBackButton. Do you've any hints as to where we can fix this? I would love to help.

@ynnob
Copy link

ynnob commented Jan 20, 2023

I think this is still not fixed.

Breaks when we navigate from a CupertinoPageScaffold page to a second CupertinoPageScaffold that implements a CupertinoNavigationBarBackButton. If you remove the CupertinoNavigationBarBackButton or add a manual onPressed method that will pop the navigation stack it will work and no assertion error is thrown.

Also if you navigate from a normal Scaffold to the CupertinoPageScaffold that implements CupertinoNavigationBarBackButton it will work. it only seems to break when the calling page is also a CupertinoPageScaffold.

CupertinoPageScaffold(
              navigationBar: CupertinoNavigationBar(
                backgroundColor: CupertinoColors.activeGreen,
                border: null,
                padding: EdgeInsetsDirectional.all(0),
                leading: CupertinoNavigationBarBackButton(
                  color: CupertinoColors.label,
                ),
              ),
              child: Center(
                child: Text('CupertinoNavigationBar'),
              ),
            )

Error:

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building CupertinoNavigationBarBackButton(dirty):
CupertinoNavigationBarBackButton should only be used in routes that can be popped
'package:flutter/src/cupertino/nav_bar.dart':
package:flutter/…/cupertino/nav_bar.dart:1
Failed assertion: line 1336 pos 9: 'currentRoute?.canPop ?? false'

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

@erkinovalim
Copy link

Is there a solution for this yet??? I am also facing this problem

@erkinovalim
Copy link

I found the solution.

When manually inserted, the [CupertinoNavigationBarBackButton] should only
be used in routes that can be popped unless a custom [onPressed] is
provided.

This is a quote from the docs. According to this, if we use our customer onPressed, it should work regardless of whether the route can be popped or not. So, we can place a Navigator.pop(context) inside an anonymous function to solve this.
Here is an example:

CupertinoNavigationBar.large(
          largeTitle: Text('Profile Page'),
          padding: EdgeInsetsDirectional.zero,
          leading: CupertinoNavigationBarBackButton(Ï
            color: CupertinoColors.activeBlue,
            previousPageTitle: 'Back',
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ),

@flutter-triage-bot flutter-triage-bot bot removed the triaged-design Triaged by Design Languages team label May 4, 2025
@flutter-triage-bot
Copy link

This issue is missing a priority label. Please set a priority label when adding the triaged-design label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
f: cupertino flutter/packages/flutter/cupertino repository found in release: 2.5 Found to occur in 2.5 found in release: 2.6 Found to occur in 2.6 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on team-design Owned by Design Languages team
Projects
None yet
Development

No branches or pull requests

6 participants