-
Notifications
You must be signed in to change notification settings - Fork 29.7k
CupertinoSheetRoute #157568
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
CupertinoSheetRoute #157568
Conversation
|
I just tried it locally and it matches the native one animation wise, but on the native one when you drag upwards, it stretches a bit, I hope you can also implement this behaviour too. |
Thanks for taking a look! Good callout on the drag upwards stretch. We're going to probably add the drag controls in a feature branch off of this one. We might not focus on getting the drag upwards behavior correct for initially landing it in master, and instead have that in a follow up issue for the sake of iteration. Same with the fullscreen version. I'll add it to the todos though so it's tracked somewhere. |
|
another notice, the status bar should automatically turn the brightness to light when the sheet is opened. |
|
This is awesome! Been using https://github.com/jamesblasco/modal_bottom_sheet and would definitely prefer a native solution! |
Thanks for the callout. We can change the status bar brightness when the sheet is opened, but it is sudden and we can't currently get the gradual transition native has with our APIs. I talked to the iOS team about that and they are aware of it. I'll open an iterative issue on that when this lands. |
7108711 to
115f61c
Compare
|
Another thing to consider is that is in dark mode the sheet in the back should lighten as the opposite of what happens in light mode it darkens, it makes the sheet in the background become visible if its black: ScreenRecording_10-31-2024.18-21-02_1.mp4 |
It looks to me like the top sheet itself has a brighter background as well so it stands out. That's probably default behavior. I'll add dark mode to the to-dos. |
Yeah it does, on ios it detects if a sheet is open and automatically sets the sheet in the fronts background color to secondaryBackground. |
justinmc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry it took me so long to review this. I played around with it locally and it seems to feel really good to my Android-user eyes. The API and examples also seem straightforward and well-integrated with Flutter's way of doing navigation.
Comparison with Swift UI
In Swift UI this is done something like this right:
.sheet(isPresented: $isSheetOpen)How about to add another sheet? How about to add another page to the current sheet?
I'm wondering what the main flows are there so that we can make them easy in Flutter too.
Other stuff
Pushing a CupertinoSheetRoute starts showing the "MBS" style navigation, then:
- Pushing another CuperinoSheetRoute appears like another tab within the MBS navigation.
- Pushing any other route does it's normal transition, as if moving away from the MBS.
- If you want to push something inside of the topmost MBS tab, you have to do that with nested navigation.
In Swift UI is it possible to do the second bullet point above?
Also, I think you mentioned it briefly before, but I wonder how you plan on implementing the feature where you can drag down to dismiss the sheet?
| return CupertinoPageRoute<void>( | ||
| builder: (BuildContext context) { | ||
| return PopScope( | ||
| canPop: settings.name != '/', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was your main motivation for adding the PopScope because of what happens when using a back gesture on iOS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After looking more closely, it seems like the main purpose is so that your nested routes can call Navigator.of(context).pop() and have it pop the root Navigator instead of the empty nested Navigator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, If you call pop() programmatically I want on the initial route in the sheet, I want it to pop the sheet. Originally it was going to an inbetween state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you also need NavigatorPopHandler?
| bool useRootNavigator = true, | ||
| bool useNestedNavigation = false, | ||
| }) { | ||
| final BuildContext topLevelSheetContext = CupertinoSheetController.maybeOf(context)?.topLevelContext ?? context; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case of nested MBSs?
| } | ||
|
|
||
| /// Docs placeholder | ||
| class CupertinoSheetTransition extends StatelessWidget { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit that some of these classes could be broken up into different files, though I know this is still a draft.
| }); | ||
|
|
||
| /// Docs placeholder | ||
| final WidgetBuilder pageBuilder; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In CupertinoPageRoute etc. I think this is just called builder. Would it be better to use that name everywhere in this PR (like also showCuperitnoSheet)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pageBuilder is used for some dialog routes. builder is more common though, so we'll go with that.
| children: <Widget>[ | ||
| CupertinoButton.filled( | ||
| onPressed: () { | ||
| showCupertinoSheet<void>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe in the final PR we should include an example that shows getting a return value from this.
|
|
||
| /// The primary delegated transition. Will slide a non [CupertinoSheetRoute] page down. | ||
| /// | ||
| /// If a [CupertinoSheetController] already exists in the stack, then it will |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the stack
Actually, if there is a regular route between the existing CupertinoSheetRoute and the new one, then it should it do the normal slide down animation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now if a regular route gets pushed to the root navigator after the sheet than the normal delegate logic will happen. I'm not 100% sure what the correct behavior should be. We may want to not play any outgoing transition at all on the sheet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it won't really be possible to push a normal route on top of a MBS and have it display as a normal route (instead it displays as an additional sheet in the MBS). Can you confirm that we're ok not supporting that? If it's not possible on native iOS or recommended against then this is probably the right call.
I'm working on that locally. There will be another draft PR branched off of this one for that. |
| }) { | ||
| final BuildContext topLevelSheetContext = CupertinoSheetController.maybeOf(context)?.topLevelContext ?? context; | ||
|
|
||
| final WidgetBuilder builder = switch (useNestedNavigation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think a
final WidgetBuilder builder;
if (!useNestedNavigation) {
builder = pageBuilder;
} else {
builder = ...
}is more readable than pattern match on a bool
| return CupertinoPageRoute<void>( | ||
| builder: (BuildContext context) { | ||
| return PopScope( | ||
| canPop: settings.name != '/', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you also need NavigatorPopHandler?
| Navigator.of(topLevelSheetContext).pop(); | ||
| }, | ||
| child: Semantics( | ||
| scopesRoute: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed? I thought the CupertinoPageRoute would already have these
| } | ||
|
|
||
| /// Docs placeholder | ||
| static CupertinoSheetController? maybeOf(BuildContext context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems weird to return a CupertinoSheetController from CupertinoSheetRoute.of. Do we really need these duplicate method?
| } | ||
|
|
||
| /// Docs placeholder | ||
| class CupertinoSheetController extends InheritedWidget { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a better name. Controller is usually a changeNotifier object in Flutter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of a inherited widget that people can access different level of context, have you thought about have a controller object that provide API to pop or push navigator route at different level?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for this is that holding a context as widget parameter is can be error prompt as it can go stale at anytime. it will be more dangerous if this is a public api
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only place that the context parameter is used is in popSheet, right? Maybe that could just take BuildContext as a parameter so that CupertinoSheetController doesn't need to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of a inherited widget that people can access different level of context, have you thought about have a controller object that provide API to pop or push navigator route at different level?
@chunhtai Are you talking about a generic controller to control nested navigation, or something specifically for this modal bottom sheet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for this modal bottom sheet. For general nested navigation one can already use NavigatorState if they possess global key
| return Navigator( | ||
| initialRoute: '/', | ||
| onGenerateRoute: (RouteSettings settings) { | ||
| return CupertinoPageRoute<void>( | ||
| builder: (BuildContext context) { | ||
| return PopScope( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider trying this out with
- go_router
- deep linking, and/or specific web-style URL requirements.
- state restoration
- Navigator.pages
I wonder what kind of requirements you'll run into to get those working. Maybe you will need some kind of builder parameter instead of just the plain boolean.
|
@MitchellGoodwin Great work so far! Looking forward for this to land 💖 |
46b2133 to
7f1a2c6
Compare
|
Added a sample that has both state restoration and nested navigation in one file. It works locally, but I'm unsure if I set it up in the ideal way. |
justinmc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some thoughts about the nested Navigator situation below.
|
|
||
| /// The primary delegated transition. Will slide a non [CupertinoSheetRoute] page down. | ||
| /// | ||
| /// If a [CupertinoSheetController] already exists in the stack, then it will |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it won't really be possible to push a normal route on top of a MBS and have it display as a normal route (instead it displays as an additional sheet in the MBS). Can you confirm that we're ok not supporting that? If it's not possible on native iOS or recommended against then this is probably the right call.
It will be possible. The previous route, which is the MBS, just wouldn't transition out and would be static. So a Cupertino page would slide in from the right, but the previous route would not slide left. On native iOS, it is possible, just a little awkward. If you navigate to a new page from within the sheet, it will be nested within the sheet. To navigate directly from the sheet to new page outside of the sheet, you have to define something like a callback in the parent view and pass it down to the sheet. I don't believe this is recommended (it's difficult to find direct guidance on this). The sheet is supposed to give options related to the context of the screen it's covering, then always go back to the original page when it's done.
I think I'm at that opinion as well. I've gotten a nested navigation example with the pages API working in several different ways, none of which make for an short sample. I think it would be pretty bloated to give a FULL sample in the PR, but could make a good blogpost/ article for the website. Again on native, I believe the way it works is the So I think removing I do not think we need or should add a Navigator by default the way SwiftUI does. That's not very "Flutter"y. cc @chunhtai |
Can you explain how to do that in Flutter code? If that's so, and as you explain it's hard to do in Swift UI, then I think I'm on board with the current approach 👍 . |
If there is no nested Navigator, than you just push a route as normal. If there is a nested Navigator, than you need to push the route to the root Navigator. So |
I have not looked at the latest change yet, so I may be under false assumption. In general, It depends on how hard the set up will be, and usually asking developer to create Navigator will require additional work like wrapping it in PopScope or navigatorPopHandler. If it does indeed have this kind of caveats AND it is a common use case, I would suggest adding a parameter to create navigator for them. Imagine we do the opposite, the developers make a bunch of mistakes and create apps with bad user experience. That is not something we want |
flutter/flutter@864d4f5...72db8f6 2025-01-13 [email protected] Roll Packages from 6554751 to 3c3bc68 (16 revisions) (flutter/flutter#161515) 2025-01-13 [email protected] Update error message for when leading/trailing width exceeds `ListTile` width and add missing test (flutter/flutter#161091) 2025-01-13 [email protected] Deprecate unused `ButtonStyleButton.iconAlignment` property (flutter/flutter#160023) 2025-01-12 [email protected] Provide monitor information. (flutter/flutter#161359) 2025-01-11 [email protected] [android_engine_test] Remove background/foreground from surface texture trampoline test. (flutter/flutter#161441) 2025-01-11 [email protected] Remove some miscellaneous references to Cirrus. (flutter/flutter#161390) 2025-01-11 [email protected] add semantics role and tab (flutter/flutter#161260) 2025-01-10 [email protected] CupertinoSheetRoute (flutter/flutter#157568) 2025-01-10 [email protected] Update `TextEditingController.text` documentation to recommend against using it in production code (flutter/flutter#157769) 2025-01-10 [email protected] � [tool] Add a wirelessly connected device name as `displayName` (flutter/flutter#160497) 2025-01-10 [email protected] FixForward: method was renamed (flutter/flutter#161431) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Adds route settings to the sheet route. From [this comment.](#157568 (comment)) ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
|
When is nested scrolling going to be added? I have tried all scrolling hacks. In the provided picture, I should be able to scroll to a third color. I think everything else is working great at this point. Also-- I had to create my own appbar to exist in a stack above the modal sheet. When using the typical navigation bar there is way too much padding from the top of the page + it disables gestures in widgets that are used in a Column or ListView towards the top; I could not figure out a solution other than a stack. |
Created an issue: #161623. It's a quick fix to enable nested scrolling. Getting the nested scrolling to smoothly interact with the drag dismiss gesture will be a longer effort.
We don't currently have anything on the backlog for adding a sheet specific app bar. Could you create an issue? In general we're looking for issues for improvements to be made to the sheet. |
I dont think new appbar is needed, the current CupertinoNavigationBar & CupertinoSliverNavigationBar are fine, all that's needed is change to their code to check if they're in a sheets context, if yes, change padding values and other small tweaks that make it match native iOS. |
for example, I tried modifying Flutter's CupertinoNavigationBar to check if the current context in in a sheet or not, if yes it should remove the top SaveArea padding, here are pics of the before and after, also the transition on push glitches the nav bar, you have to explicitly set the set transitionBetweenRoutes to false in the sheets nav bar, it should automatically tell if its in a sheet and disable it.
|
Fixes flutter#42560 ### Updated 12/04/24 Adds a CupertinoSheetRoute which displays an iOS style sheet, while giving the previous route a delegated transition to sync up correctly. There's a lot of sample files in this draft showing different use cases for the sake of reviewing the PR. We'll want to probably go down to about two before this PR lands. **TODO in this PR** - [x] Write actual documentation - [x] Write tests **TODO in a feature branch, and will be merged with this PR** - [ ] Add swipe down to dismiss **TODO in a follow up PR** - [ ] Stretching on swipe up - [ ] Add a fullscreen version - [x] Dark mode theming How it currently compares, with the simple case and nested navigation: | Flutter | Native| | ------------- | ------------- | |  | | |  |  | Update:  Now the status bar will transition from dark to light text so that it's visible after the transition. `cupertino_sheet.0.dart` has an example of what it looks like to do a simple case. It's fairly straightforward. `cupertino_sheet.1.dart` shows one with nested navigation. It's necessary to add a `Navigator` if showing page navigation within the sheet is wanted. I'm thinking adding an API option that auto sets this up may be needed as there are some pitfalls. `cupertino_sheet.2.dart` functionally does the same as above but uses the `showCupertinoSheet` to reduce boilerplate. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Adds route settings to the sheet route. From [this comment.](flutter#157568 (comment)) ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
|
From which version of Flutter will CupertinoSheetRoute be available? |
The next stable version I think, you can try it now by switching to the main channel, if you want to try it without switching channels, you can copy the sheet code from this PR and directly add it to your flutter project which I did and works fine. |
…162181) Working on the cupertino nav bars recently gave me some context on those widgets, so when I saw this [comment](#157568 (comment)) I was inspired to add a fix :) Thanks @MaherSafadii for [starting the exploration](#157568 (comment)) and also for the very helpful [screenshots](#162021 (comment)). Removes the following when CupertinoNavigationBar/CupertinoSliverNavigationBar is used in a CupertinoSheetRoute: - Unneeded back button - Superfluous top padding in CupertinoNavigationBar - Full page route transitions ## Before: https://github.com/user-attachments/assets/a6da3957-0cff-4491-9380-bbc676ac799d ## After: https://github.com/user-attachments/assets/37cd1628-a47e-44aa-85c7-abceda6e7944 <details> <summary>Sample code</summary> ```dart // Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:flutter/cupertino.dart'; /// Flutter code sample for [CupertinoSheetRoute]. class CupertinoSheetApp extends StatelessWidget { const CupertinoSheetApp({super.key}); @OverRide Widget build(BuildContext context) { return const CupertinoApp(title: 'Cupertino Sheet', home: HomePage()); } } class HomePage extends StatelessWidget { const HomePage({super.key}); @OverRide Widget build(BuildContext context) { return CupertinoPageScaffold( navigationBar: const CupertinoNavigationBar( middle: Text('Sheet Example'), automaticBackgroundVisibility: false, ), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ CupertinoButton.filled( onPressed: () { Navigator.of(context).push( CupertinoSheetRoute<void>( builder: (BuildContext context) => const _SheetScaffold(), ), ); }, child: const Text('Open Bottom Sheet'), ), ], ), ), ); } } class _SheetScaffold extends StatelessWidget { const _SheetScaffold(); @OverRide Widget build(BuildContext context) { return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( backgroundColor: CupertinoColors.systemGrey.withOpacity(0.5), middle: const Text('CupertinoNavigationBar Sample'), automaticBackgroundVisibility: false, ), child: Column( children: <Widget>[ Container(height: 50, color: CupertinoColors.systemRed), Container(height: 50, color: CupertinoColors.systemGreen), Container(height: 50, color: CupertinoColors.systemBlue), Container(height: 50, color: CupertinoColors.systemYellow), Center( child: CupertinoButton.filled( onPressed: () { Navigator.of(context).push( CupertinoSheetRoute<void>( builder: (BuildContext context) => const SliverNavBarExample(), ), ); }, child: const Text('Open Bottom Sheet'), ), ) ], ), ); } } class SliverNavBarExample extends StatelessWidget { const SliverNavBarExample({super.key}); @OverRide Widget build(BuildContext context) { return CupertinoPageScaffold( child: CustomScrollView( slivers: <Widget>[ const CupertinoSliverNavigationBar( leading: Icon(CupertinoIcons.person_2), largeTitle: Text('Contacts'), trailing: Icon(CupertinoIcons.add_circled), ), SliverFillRemaining( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ const Text('Drag me up', textAlign: TextAlign.center), CupertinoButton.filled( onPressed: () {}, child: const Text('Bottom Automatic mode'), ), CupertinoButton.filled( onPressed: () {}, child: const Text('Bottom Always mode'), ), ], ), ), ), ], ), ); } } ``` </details> Fixes [Cupertino navbars apply too much top padding within a sheet](#162021). ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
) CupertinoSheetRoute is a new widget added in 3.29 as a part of #157568. #161696 fixes #161623, which was an issue where you could not put scrollable content in the sheet, which is expected behavior. CupertinoSheetRoute has been a highly requested widget so is expected to get a lot of use. Impacted users: anyone using the CupertinoSheetRoute with scrollable content, which should be a common use case. Impact description: not being able to scroll within the sheet would create a very bad first impression and leave the sheet unusable for a lot of apps. Workaround: None. Risk: This is a brand new widget, so none. Test Coverage (Are you confident that your fix is well-tested by automated tests?): Yes, the fix has regression tests. Validation Steps (What are the steps to validate that this fix works?): Create a CupertinoSheetRoute with scrollable content that expands past the size of the sheet. #161623 has a code sample.
flutter/flutter@864d4f5...72db8f6 2025-01-13 [email protected] Roll Packages from 6554751 to 3c3bc68 (16 revisions) (flutter/flutter#161515) 2025-01-13 [email protected] Update error message for when leading/trailing width exceeds `ListTile` width and add missing test (flutter/flutter#161091) 2025-01-13 [email protected] Deprecate unused `ButtonStyleButton.iconAlignment` property (flutter/flutter#160023) 2025-01-12 [email protected] Provide monitor information. (flutter/flutter#161359) 2025-01-11 [email protected] [android_engine_test] Remove background/foreground from surface texture trampoline test. (flutter/flutter#161441) 2025-01-11 [email protected] Remove some miscellaneous references to Cirrus. (flutter/flutter#161390) 2025-01-11 [email protected] add semantics role and tab (flutter/flutter#161260) 2025-01-10 [email protected] CupertinoSheetRoute (flutter/flutter#157568) 2025-01-10 [email protected] Update `TextEditingController.text` documentation to recommend against using it in production code (flutter/flutter#157769) 2025-01-10 [email protected] � [tool] Add a wirelessly connected device name as `displayName` (flutter/flutter#160497) 2025-01-10 [email protected] FixForward: method was renamed (flutter/flutter#161431) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
flutter/flutter@864d4f5...72db8f6 2025-01-13 [email protected] Roll Packages from 6554751 to 3c3bc68 (16 revisions) (flutter/flutter#161515) 2025-01-13 [email protected] Update error message for when leading/trailing width exceeds `ListTile` width and add missing test (flutter/flutter#161091) 2025-01-13 [email protected] Deprecate unused `ButtonStyleButton.iconAlignment` property (flutter/flutter#160023) 2025-01-12 [email protected] Provide monitor information. (flutter/flutter#161359) 2025-01-11 [email protected] [android_engine_test] Remove background/foreground from surface texture trampoline test. (flutter/flutter#161441) 2025-01-11 [email protected] Remove some miscellaneous references to Cirrus. (flutter/flutter#161390) 2025-01-11 [email protected] add semantics role and tab (flutter/flutter#161260) 2025-01-10 [email protected] CupertinoSheetRoute (flutter/flutter#157568) 2025-01-10 [email protected] Update `TextEditingController.text` documentation to recommend against using it in production code (flutter/flutter#157769) 2025-01-10 [email protected] � [tool] Add a wirelessly connected device name as `displayName` (flutter/flutter#160497) 2025-01-10 [email protected] FixForward: method was renamed (flutter/flutter#161431) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md



Fixes #42560
Updated 12/04/24
Adds a CupertinoSheetRoute which displays an iOS style sheet, while giving the previous route a delegated transition to sync up correctly.
There's a lot of sample files in this draft showing different use cases for the sake of reviewing the PR. We'll want to probably go down to about two before this PR lands.
TODO in this PR
TODO in a feature branch, and will be merged with this PR
TODO in a follow up PR
How it currently compares, with the simple case and nested navigation:
Update:

Now the status bar will transition from dark to light text so that it's visible after the transition.
cupertino_sheet.0.darthas an example of what it looks like to do a simple case. It's fairly straightforward.cupertino_sheet.1.dartshows one with nested navigation. It's necessary to add aNavigatorif showing page navigation within the sheet is wanted. I'm thinking adding an API option that auto sets this up may be needed as there are some pitfalls.cupertino_sheet.2.dartfunctionally does the same as above but uses theshowCupertinoSheetto reduce boilerplate.Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.