showWithCustomHeaderUiKitView static method
Future<void>
showWithCustomHeaderUiKitView({
- required BuildContext context,
- required String title,
- required Widget builder(),
- List<
CNSheetDetent> detents = const [CNSheetDetent.large], - bool prefersGrabberVisible = true,
- bool isModal = false,
- bool prefersEdgeAttachedInCompactHeight = false,
- bool widthFollowsPreferredContentSizeWhenEdgeAttached = false,
- double? preferredCornerRadius,
- double? headerTitleSize,
- FontWeight? headerTitleWeight,
- Color? headerTitleColor,
- double? headerHeight,
- Color? headerBackgroundColor,
- bool showHeaderDivider = true,
- Color? headerDividerColor,
- String closeButtonPosition = 'trailing',
- String closeButtonIcon = 'xmark',
- double? closeButtonSize,
- Color? closeButtonColor,
Shows a native sheet with custom Flutter widget content using UiKitView.
This is the ULTIMATE GOAL - it combines:
- Native UISheetPresentationController (real iOS sheet with blur, animations, detents)
- Custom Flutter widgets embedded via UiKitView
- Non-modal behavior (interact with background while sheet is open)
- Custom header with title and close button
Unlike showCustomContent which uses Flutter's modal popup, this uses a real
native iOS sheet presentation, giving you the authentic iOS look and feel while
still allowing full customization of the content area with Flutter widgets.
Perfect for:
- Formatting toolbars (like Apple Notes)
- Inspector panels
- Tool palettes
- Any auxiliary UI that needs to stay visible during work
Example:
await CNNativeSheet.showWithCustomHeaderUiKitView(
context: context,
title: 'Format',
builder: (context) => Column(
children: [
Row(
children: [
IconButton(icon: Icon(CupertinoIcons.bold), onPressed: () {}),
IconButton(icon: Icon(CupertinoIcons.italic), onPressed: () {}),
],
),
],
),
detents: [CNSheetDetent.custom(280)],
isModal: false, // Allow background interaction!
);
Implementation
static Future<void> showWithCustomHeaderUiKitView({
required BuildContext context,
required String title,
required Widget Function(BuildContext) builder,
List<CNSheetDetent> detents = const [CNSheetDetent.large],
bool prefersGrabberVisible = true,
bool isModal = false,
bool prefersEdgeAttachedInCompactHeight = false,
bool widthFollowsPreferredContentSizeWhenEdgeAttached = false,
double? preferredCornerRadius,
double? headerTitleSize,
FontWeight? headerTitleWeight,
Color? headerTitleColor,
double? headerHeight,
Color? headerBackgroundColor,
bool showHeaderDivider = true,
Color? headerDividerColor,
String closeButtonPosition = 'trailing',
String closeButtonIcon = 'xmark',
double? closeButtonSize,
Color? closeButtonColor,
}) async {
if (isModal) {
// For modal sheets, use CupertinoModalPopupRoute
await Navigator.of(context).push(
CupertinoModalPopupRoute(
builder: (context) => _NativeSheetWithUiKitView(
title: title,
builder: builder,
detents: detents,
prefersGrabberVisible: prefersGrabberVisible,
isModal: isModal,
prefersEdgeAttachedInCompactHeight:
prefersEdgeAttachedInCompactHeight,
widthFollowsPreferredContentSizeWhenEdgeAttached:
widthFollowsPreferredContentSizeWhenEdgeAttached,
preferredCornerRadius: preferredCornerRadius,
headerTitleSize: headerTitleSize,
headerTitleWeight: headerTitleWeight,
headerTitleColor: headerTitleColor,
headerHeight: headerHeight,
headerBackgroundColor: headerBackgroundColor,
showHeaderDivider: showHeaderDivider,
headerDividerColor: headerDividerColor,
closeButtonPosition: closeButtonPosition,
closeButtonIcon: closeButtonIcon,
closeButtonSize: closeButtonSize,
closeButtonColor: closeButtonColor,
),
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) => _NativeSheetWithUiKitView(
title: title,
builder: builder,
detents: detents,
prefersGrabberVisible: prefersGrabberVisible,
isModal: isModal,
prefersEdgeAttachedInCompactHeight:
prefersEdgeAttachedInCompactHeight,
widthFollowsPreferredContentSizeWhenEdgeAttached:
widthFollowsPreferredContentSizeWhenEdgeAttached,
preferredCornerRadius: preferredCornerRadius,
headerTitleSize: headerTitleSize,
headerTitleWeight: headerTitleWeight,
headerTitleColor: headerTitleColor,
headerHeight: headerHeight,
headerBackgroundColor: headerBackgroundColor,
showHeaderDivider: showHeaderDivider,
headerDividerColor: headerDividerColor,
closeButtonPosition: closeButtonPosition,
closeButtonIcon: closeButtonIcon,
closeButtonSize: closeButtonSize,
closeButtonColor: closeButtonColor,
onClose: () {
overlayEntry.remove();
},
),
);
overlay.insert(overlayEntry);
}
}