showWithCustomHeaderUiKitView static method

Future<void> showWithCustomHeaderUiKitView({
  1. required BuildContext context,
  2. required String title,
  3. required Widget builder(
    1. BuildContext
    ),
  4. List<CNSheetDetent> detents = const [CNSheetDetent.large],
  5. bool prefersGrabberVisible = true,
  6. bool isModal = false,
  7. bool prefersEdgeAttachedInCompactHeight = false,
  8. bool widthFollowsPreferredContentSizeWhenEdgeAttached = false,
  9. double? preferredCornerRadius,
  10. double? headerTitleSize,
  11. FontWeight? headerTitleWeight,
  12. Color? headerTitleColor,
  13. double? headerHeight,
  14. Color? headerBackgroundColor,
  15. bool showHeaderDivider = true,
  16. Color? headerDividerColor,
  17. String closeButtonPosition = 'trailing',
  18. String closeButtonIcon = 'xmark',
  19. double? closeButtonSize,
  20. 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);
  }
}