showWithCustomHeaderWidget static method
Future<void>
showWithCustomHeaderWidget({
- required BuildContext context,
- required Widget headerBuilder(),
- required Widget contentBuilder(),
- List<
CNSheetDetent> detents = const [CNSheetDetent.large], - bool prefersGrabberVisible = true,
- bool isModal = false,
- bool prefersEdgeAttachedInCompactHeight = false,
- bool widthFollowsPreferredContentSizeWhenEdgeAttached = false,
- double? preferredCornerRadius,
- double? headerHeight,
- Color? headerBackgroundColor,
- bool showHeaderDivider = true,
- Color? headerDividerColor,
- VoidCallback? onClose,
Shows a native sheet with custom Flutter widget header and content using UiKitView.
Similar to showWithCustomHeaderUiKitView but allows the header (title/subtitle) to be
custom Flutter widgets instead of just strings. This gives you full flexibility to style
the header while maintaining the native iOS sheet presentation.
Features:
- Native UISheetPresentationController (real iOS sheet)
- Custom Flutter widget header (title as a widget!)
- Custom Flutter widgets as content via UiKitView
- Non-modal behavior (interact with background)
- Native feel and animations
Example:
await CNNativeSheet.showWithCustomHeaderWidget(
context: context,
headerBuilder: (context) => Column(
children: [
Text('Format', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
Text('Text formatting options', style: TextStyle(fontSize: 13, color: Colors.grey)),
],
),
contentBuilder: (context) => Column(
children: [
Row(
children: [
IconButton(icon: Icon(CupertinoIcons.bold), onPressed: () {}),
IconButton(icon: Icon(CupertinoIcons.italic), onPressed: () {}),
],
),
],
),
detents: [CNSheetDetent.custom(300)],
isModal: false,
);
Implementation
static Future<void> showWithCustomHeaderWidget({
required BuildContext context,
required Widget Function(BuildContext) headerBuilder,
required Widget Function(BuildContext) contentBuilder,
List<CNSheetDetent> detents = const [CNSheetDetent.large],
bool prefersGrabberVisible = true,
bool isModal = false,
bool prefersEdgeAttachedInCompactHeight = false,
bool widthFollowsPreferredContentSizeWhenEdgeAttached = false,
double? preferredCornerRadius,
double? headerHeight,
Color? headerBackgroundColor,
bool showHeaderDivider = true,
Color? headerDividerColor,
VoidCallback? onClose,
}) async {
if (isModal) {
// For modal sheets, use CupertinoModalPopupRoute
await Navigator.of(context).push(
CupertinoModalPopupRoute(
builder: (context) => _NativeSheetWithCustomWidgetHeader(
headerBuilder: headerBuilder,
contentBuilder: contentBuilder,
detents: detents,
prefersGrabberVisible: prefersGrabberVisible,
isModal: isModal,
prefersEdgeAttachedInCompactHeight:
prefersEdgeAttachedInCompactHeight,
widthFollowsPreferredContentSizeWhenEdgeAttached:
widthFollowsPreferredContentSizeWhenEdgeAttached,
preferredCornerRadius: preferredCornerRadius,
headerHeight: headerHeight,
headerBackgroundColor: headerBackgroundColor,
showHeaderDivider: showHeaderDivider,
headerDividerColor: headerDividerColor,
onClose: onClose,
),
barrierDismissible: false,
barrierColor: CupertinoColors.black.withOpacity(0.4),
),
);
} else {
// For non-modal sheets, use Overlay to allow background interaction
final overlay = Overlay.of(context);
late OverlayEntry overlayEntry;
overlayEntry = OverlayEntry(
builder: (context) => _NativeSheetWithCustomWidgetHeader(
headerBuilder: headerBuilder,
contentBuilder: contentBuilder,
detents: detents,
prefersGrabberVisible: prefersGrabberVisible,
isModal: isModal,
prefersEdgeAttachedInCompactHeight:
prefersEdgeAttachedInCompactHeight,
widthFollowsPreferredContentSizeWhenEdgeAttached:
widthFollowsPreferredContentSizeWhenEdgeAttached,
preferredCornerRadius: preferredCornerRadius,
headerHeight: headerHeight,
headerBackgroundColor: headerBackgroundColor,
showHeaderDivider: showHeaderDivider,
headerDividerColor: headerDividerColor,
onClose: () {
overlayEntry.remove();
onClose?.call();
},
),
);
overlay.insert(overlayEntry);
}
}