CNAlert class
A native alert dialog: UIAlertController on iOS, NSAlert on macOS.
On iOS this presents a real UIAlertController in
UIAlertController.Style.alert, so the dialog is the system control: system
typography and button dividers, the destructive red, VoiceOver, Dynamic
Type, and — on iOS 26 — the Liquid Glass appearance. Because that appearance
comes from the OS with no opt-in, the native path is used on every supported
iOS version rather than being gated on iOS 26.
On macOS this presents a real NSAlert as a sheet on the app's window
(beginSheetModal, never a blocking modal loop), on every supported macOS
version:
- Buttons follow AppKit's order: the CNAlertAction.isDefault action at
the trailing edge, answering Return, the CNAlertAction.isCancel action
next to it, answering Escape, then the others. Without an
isDefaultaction the first action that is not cancel takes Return, unless it is destructive. - CNAlertAction.isDestructive sets
NSButton.hasDestructiveAction. - CNAlertTextFields are
NSTextFields (NSSecureTextFieldwhen obscured) in the alert's accessory view; the first one has the focus. - The alert shows the app icon, as every
NSAlertdoes.
On every other platform the alert falls back to a CupertinoAlertDialog
presented through showCupertinoDialog with barrierDismissible: false,
matching UIKit — a .alert cannot be dismissed by tapping outside.
Basic usage
final result = await CNAlert.show<String>(
context: context,
title: 'Delete photo?',
message: 'This cannot be undone.',
actions: const [
CNAlertAction(label: 'Cancel', isCancel: true),
CNAlertAction(label: 'Delete', value: 'delete', isDestructive: true),
],
);
if (result?.value == 'delete') _deletePhoto();
With a text field
final result = await CNAlert.show<String>(
context: context,
title: 'Rename',
textFields: const [
CNAlertTextField(placeholder: 'Name', initialText: 'Untitled'),
],
actions: const [
CNAlertAction(label: 'Cancel', isCancel: true),
CNAlertAction(label: 'Save', value: 'save', isDefault: true),
],
);
if (result?.value == 'save') rename(result!.textFields.first);
What this deliberately does not do
- No custom content.
UIAlertControllerhas no public API for an arbitrary content view; the properties that would allow it (contentViewController,_headerContentViewController) are private. - No icons on actions.
UIAlertActionhas no public image property. - No severity.
UIAlertController.severityis Mac Catalyst only. - No anchoring. An alert is always centred; anchoring to a source view is an action-sheet behaviour.
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 Methods
-
show<
T> ({required BuildContext context, required List< CNAlertAction< actions, String? title, String? message, List<T> >CNAlertTextField> textFields = const <CNAlertTextField>[], bool throwOnFailure = false, String? fontFamily, CNDialogTextStyle? titleStyle, CNDialogTextStyle? messageStyle, CNDialogTextStyle? actionStyle, TextDirection? textDirection}) → Future<CNAlertResult< T> ?> - Presents the alert and resolves to what the user answered.