Skip to content

CupertinoSheet example broken state with programmatic pop #175390

Closed

Description

@justinmc

The "Go Back" button in the cupertino_sheet.1.dart example leaves the app in a broken state.

Steps to reproduce

  1. Run the example in cupertino_sheet.1.dart.
  2. Open the bottom sheet.
  3. Press "Go Back".

Expected results

The bottom sheet closes fully.

Actual results

The bottom sheet disappears, but the underlying route does not animate. The app is frozen and can't be interacted with.

Screen.Recording.2025-09-15.at.3.46.50.PM.mov

FYI @MitchellGoodwin

Activity

  1. tirth-patel-nc commented on Sep 16, 2025

    @tirth-patel-nc
    Member

    @justinmc thanks for the report. Most likely this is dupe of #171878 (comment). Labelling it for team's tracking.

  2. added
    p: cupertino_uicupertino_ui package in flutter/packages
    d: api docsIssues with https://api.flutter.dev/
    frameworkflutter/packages/flutter repository. See also f: labels.
    f: routesNavigator, Router, and related APIs.
    team-designOwned by Design Languages team
    and removed
    in triagePresently being triaged by the triage team
    on Sep 16, 2025
  3. added
    P2Important issues not at the top of the work list
    triaged-designTriaged by Design Languages team
    on Sep 17, 2025
  4. ksokolovskyi commented on Sep 19, 2025

    @ksokolovskyi
    Contributor

    Hi @justinmc @MitchellGoodwin, I've taken a look at the source code and have some feedback. We have a PopScope widget that closes the sheet when the user attempts to pop the last page.

    return PopScope(
    canPop: false,
    onPopInvokedWithResult: (bool didPop, Object? result) {
    if (didPop) {
    return;
    }
    Navigator.of(context, rootNavigator: true).pop(result);
    },
    child: effectivePageBuilder!(context),
    );

    However, this works only when the back button is used, as in that case didPop will be false. When we use Navigator.of(context).pop(), the route is getting popped, and didPop is true. If I remove the check for didPop, we end up with a weird UI:

    bad_example.mov

    For now, I don't know a way to prevent the route pop after Navigator.of(context).pop() call.

    What I suggest is updating the example app. There is no canPop() check before calling pop(). You may similarly break any app by simply calling Navigator.of(context).pop() while you are on the initial route.

    To prevent the issue, we can add an explicit canPop check like the following:

    CupertinoButton.filled(
      onPressed: () {
        final navigator = Navigator.of(context);
        if (navigator.canPop()) {
          navigator.pop();
        } else {
          CupertinoSheetRoute.popSheet(context);
        }
      },
      child: const Text('Go Back'),
    ),
    example.mov

    What do you think?

  5. MitchellGoodwin commented on Sep 19, 2025

    @MitchellGoodwin
    Contributor

    For now, I don't know a way to prevent the route pop after Navigator.of(context).pop() call.

    What I suggest is updating the example app. There is no canPop() check before calling pop(). You may similarly break any app by simply calling Navigator.of(context).pop() while you are on the initial route.

    I agree that it's simpler to update the example app. But I think you can get the same result by just replacing navigator.pop() with navigator.maybePop().

  6. ksokolovskyi commented on Sep 19, 2025

    @ksokolovskyi
    Contributor

    For now, I don't know a way to prevent the route pop after Navigator.of(context).pop() call.

    What I suggest is updating the example app. There is no canPop() check before calling pop(). You may similarly break any app by simply calling Navigator.of(context).pop() while you are on the initial route.

    I agree that it's simpler to update the example app. But I think you can get the same result by just replacing navigator.pop() with navigator.maybePop().

    We could definitely use maybePop to omit popping the initial page, but then the sheet will remain open, and tapping on Go Back will have no effect. Or may I miss something?

  7. MitchellGoodwin commented on Sep 19, 2025

    @MitchellGoodwin
    Contributor

    The sheet will close. maybePop will hit PopScope with a didPop of false.

  8. ksokolovskyi commented on Sep 19, 2025

    @ksokolovskyi
    Contributor

    The sheet will close. maybePop will hit PopScope with a didPop of false.

    Indeed, thanks a lot for the explanation! I was always thinking that maybePop just checks canPop and then calls pop.

  9. rkishan516 commented on Sep 21, 2025

    @rkishan516
    Contributor

    @ksokolovskyi you're changing this, or can i go ahead and change?

  10. ksokolovskyi commented on Sep 21, 2025

    @ksokolovskyi
    Contributor

    @rkishan516, if you are ready to work on this issue, feel free to take it. Thanks!

  11. rkishan516 commented on Sep 21, 2025

    @rkishan516
    Contributor

    Sure, let me make initial change then.

  12. added a commit that references this issue on Sep 24, 2025
    f9b7f8a
  13. added a commit that references this issue on Sep 24, 2025
    923a971
  14. github-actions commented on Oct 8, 2025

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

  15. locked as resolved and limited conversation to collaborators on Oct 8, 2025
  16. added a commit that references this issue on Dec 10, 2025
    044b155
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listd: api docsIssues with https://api.flutter.dev/d: examplesSample code and demosf: routesNavigator, Router, and related APIs.frameworkflutter/packages/flutter repository. See also f: labels.p: cupertino_uicupertino_ui package in flutter/packagesr: fixedIssue is closed as already fixed in a newer versionteam-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions