如何去除CupertinoSliverNavigationBar可折叠空间,实现窄款导航栏?
I've run into this exact issue before—dealing with that frustrating collapsible space from CupertinoSliverNavigationBar when all you want is a compact, fixed-height bar for your scrollable content. Here are two reliable fixes:
Option 1: Tweak CupertinoSliverNavigationBar Directly
Contrary to what it might seem, largeTitle isn't actually a mandatory property. Setting it to null eliminates the collapsible area entirely, and you can adjust other properties to get the slim look you need:
@override Widget build(BuildContext context) { return CupertinoPageScaffold( child: CustomScrollView( slivers: <Widget>[ CupertinoSliverNavigationBar( // Remove the collapsible large title section largeTitle: null, middle: Text('Search', style: TextStyle(fontSize: 15.5)), trailing: IconButton( icon: Icon( IconData(0xe900, fontFamily: 'message6'), color: Colors.black, size: 25.0, ), onPressed: () { // Navigator.pushNamed(context, '/chat'); }, ), // Optional: Match the default bottom border style border: Border( bottom: BorderSide( color: CupertinoColors.systemGrey4, width: 0.5, ), ), // Remove extra padding for a tighter fit padding: EdgeInsetsDirectional.zero, ), // Add your scrollable content here (e.g., SliverList/SliverGrid) SliverList( delegate: SliverChildBuilderDelegate( (context, index) => ListTile(title: Text('Item $index')), childCount: 50, ), ), ], ), ); }
This gives you a slim, non-collapsing navigation bar that plays nicely with CustomScrollView.
Option 2: Wrap CupertinoNavigationBar in SliverPersistentHeader
If you prefer using the standard CupertinoNavigationBar (which has no built-in collapsing behavior), wrap it in a SliverPersistentHeader to make it compatible with CustomScrollView:
First, create a delegate class to define the fixed header behavior:
class _FixedNavigationBarDelegate extends SliverPersistentHeaderDelegate { final Widget child; _FixedNavigationBarDelegate({required this.child}); @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { return child; } // Match the default height of CupertinoNavigationBar @override double get maxExtent => CupertinoNavigationBar().preferredSize.height; @override double get minExtent => CupertinoNavigationBar().preferredSize.height; @override bool shouldRebuild(_FixedNavigationBarDelegate oldDelegate) { return child != oldDelegate.child; } }
Then implement it in your CustomScrollView:
@override Widget build(BuildContext context) { return CupertinoPageScaffold( child: CustomScrollView( slivers: <Widget>[ SliverPersistentHeader( pinned: true, // Keep the bar visible while scrolling delegate: _FixedNavigationBarDelegate( child: CupertinoNavigationBar( middle: Text('Search', style: TextStyle(fontSize: 15.5)), trailing: IconButton( icon: Icon( IconData(0xe900, fontFamily: 'message6'), color: Colors.black, size: 25.0, ), onPressed: () { // Navigator.pushNamed(context, '/chat'); }, ), ), ), ), // Your scrollable content here SliverList( delegate: SliverChildBuilderDelegate( (context, index) => ListTile(title: Text('Item $index')), childCount: 50, ), ), ], ), ); }
This approach gives you full control—no unexpected collapsible space, just a fixed-height bar that stays pinned as you scroll through content.
内容的提问来源于stack exchange,提问作者K.chim

