CNNativeSheet class

A native iOS sheet over the Flutter app, drawn by UIKit and SwiftUI.

The sheet rests at one of its CNSheetDetents and can be dragged between them. Above the detent passed as undimmedDetent, the Flutter app behind it stays undimmed and keeps receiving touches, so a map behind a small or medium sheet can still be panned. With dismissible: false the sheet never closes by dragging, as in apps whose main screen is a map with a sheet over it. On iOS 26 the sheet is Liquid Glass at its partial heights.

The content is native, built from CNSheetPages: a title, navigation bar buttons and a list of CNListItems per page, and a tab bar inside the sheet when there is more than one page. Flutter widgets cannot be placed inside the sheet: an iOS app has a single Flutter view, which stays behind the sheet.

On macOS the sheet is the window's inspector: the panel at the trailing side of the window, beside the Flutter content (an NSSplitViewController inspector item, shared with the sidebar of CNTabBarNative). The pages are the same: each page's title, buttons and rows, and a segmented switcher at the top for more than one page (the badge counts follow the symbols). The events are the same, except onDetentChanged: an inspector has no detents, so detents, initialDetent, undimmedDetent, showGrabber and setDetent are ignored. A dismissible sheet has a close button and can be closed by dragging the inspector's divider; both call onDismissed. A sheet that is not dismissible stays until dismiss. The Flutter app beside the inspector stays usable.

iOS 17 and later, and macOS. Elsewhere show does nothing and returns false.

await CNNativeSheet.show(
  pages: [
    CNSheetPage(
      title: 'People',
      sfSymbol: CNSymbol('person.2.fill'),
      buttons: [CNSheetButton(id: 'add', sfSymbol: CNSymbol('plus'), label: 'Add')],
      items: [CNListItem(title: 'Ada', subtitle: 'London · Now', trailingText: '2 km')],
    ),
    CNSheetPage(title: 'Devices', sfSymbol: CNSymbol('macbook.and.iphone')),
  ],
  detents: const [CNSheetDetent.collapsed, CNSheetDetent.medium, CNSheetDetent.large],
  initialDetent: CNSheetDetent.medium,
  undimmedDetent: CNSheetDetent.medium,
  dismissible: false,
  onButtonTap: (page, id) {},
  onItemTap: (page, index) {},
);

Properties

hashCode → int
The hash code for this object.
no setterinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Properties

isShown → bool
Whether the sheet is showing.
no setter

Static Methods

dismiss() → Future<void>
Dismisses the sheet.
setBadgeCounts(List<int?> badgeCounts) → Future<void>
Updates the badge count of each page's tab. Null or 0 clears a badge.
setBrightness({required bool isDark}) → Future<void>
Switches the sheet between light and dark appearance.
setDetent(CNSheetDetent detent) → Future<void>
Moves the sheet to detent, one of the detents it was shown with. Ignored on macOS, where the inspector has no detents.
setItems({required int page, required List<CNListItem> items}) → Future<void>
Replaces the rows of the page at page.
setSelectedPage(int index) → Future<void>
Selects the page at index.
show({required List<CNSheetPage> pages, List<CNSheetDetent> detents = const [CNSheetDetent.medium, CNSheetDetent.large], CNSheetDetent? initialDetent, CNSheetDetent? undimmedDetent, bool dismissible = true, bool showGrabber = true, int selectedPage = 0, Color? tintColor, bool? isDark, void onDetentChanged(CNSheetDetent detent)?, void onPageSelected(int page)?, void onItemTap(int page, int index)?, void onButtonTap(int page, String id)?, VoidCallback? onDismissed}) → Future<bool>
Presents the sheet with pages.