Expo UI and Router for iOSExpo SDK 57 and later, iOS only
Components

Alert

A SwiftUI Alert component for presenting native iOS alert dialogs.

Expo UI Alert matches the official SwiftUI alert API and presents a native iOS alert dialog with a title, actions, and an optional message.

Alert is the centered modal counterpart to ConfirmationDialog, which renders as an action sheet from the bottom of the screen. Both share the same trigger/actions/message slot model so callers can swap between them by changing the component name.

Usage

Basic alert

Use Alert.Trigger to define the visible element and Alert.Actions to provide the dialog buttons.

import { useState } from 'react';
import { Host, Alert, Button } from '@expo/ui/swift-ui';

export default function BasicAlertExample() {
  const [isPresented, setIsPresented] = useState(false);

  return (
    <Host style={{ flex: 1 }}>
      <Alert
        title="Saved"
        isPresented={isPresented}
        onIsPresentedChange={setIsPresented}>
        <Alert.Trigger>
          <Button
            label="Show alert"
            onPress={() => setIsPresented(true)}
          />
        </Alert.Trigger>
        <Alert.Actions>
          <Button
            label="OK"
            onPress={() => setIsPresented(false)}
          />
        </Alert.Actions>
      </Alert>
    </Host>
  );
}
Alert titled Saved with a single OK button, above the Show alert trigger
Alert titled Saved with a single OK button, above the Show alert trigger

Cancel and confirm

Combine role="cancel" with a confirm button to build a standard yes/no alert.

import { useState } from 'react';
import { Host, Alert, Button, Text } from '@expo/ui/swift-ui';

export default function CancelConfirmAlertExample() {
  const [isPresented, setIsPresented] = useState(false);

  return (
    <Host style={{ flex: 1 }}>
      <Alert
        title="Sign out?"
        isPresented={isPresented}
        onIsPresentedChange={setIsPresented}>
        <Alert.Trigger>
          <Button
            label="Sign out"
            onPress={() => setIsPresented(true)}
          />
        </Alert.Trigger>
        <Alert.Actions>
          <Button
            label="Sign out"
            onPress={() => console.log('Signed out')}
          />
          <Button label="Cancel" role="cancel" />
        </Alert.Actions>
        <Alert.Message>
          <Text>
            You will need to sign in again to access your account.
          </Text>
        </Alert.Message>
      </Alert>
    </Host>
  );
}
Alert titled Sign out? with a message and Cancel and Sign out buttons
Alert titled Sign out? with a message and Cancel and Sign out buttons

Destructive action

Use role="destructive" on a Button inside Alert.Actions to style it as a destructive action.

import { useState } from 'react';
import { Host, Alert, Button, Text } from '@expo/ui/swift-ui';

export default function DestructiveAlertExample() {
  const [isPresented, setIsPresented] = useState(false);

  return (
    <Host style={{ flex: 1 }}>
      <Alert
        title="Delete account?"
        isPresented={isPresented}
        onIsPresentedChange={setIsPresented}>
        <Alert.Trigger>
          <Button
            label="Delete account"
            role="destructive"
            onPress={() => setIsPresented(true)}
          />
        </Alert.Trigger>
        <Alert.Actions>
          <Button
            label="Delete"
            role="destructive"
            onPress={() => {
              console.log('Deleted');
              setIsPresented(false);
            }}
          />
          <Button label="Cancel" role="cancel" />
        </Alert.Actions>
        <Alert.Message>
          <Text>
            This permanently deletes your account and all data. This
            cannot be undone.
          </Text>
        </Alert.Message>
      </Alert>
    </Host>
  );
}
Alert titled Delete account? with a message, a Cancel button, and a red Delete button
Alert titled Delete account? with a message, a Cancel button, and a red Delete button

API

import { Alert } from '@expo/ui/swift-ui';

Component

Alert

Type: React.Element<AlertProps>

Alert presents a SwiftUI alert with a title, optional message, and action buttons.

See: Official SwiftUI documentation.

Props of the Alert component.

AlertProps

children

Type: React.ReactNode

The contents of the alert. Should include Alert.Trigger, Alert.Actions, and optionally Alert.Message.

isPresented

Optional • Type: boolean

Whether the alert is presented.

onIsPresentedChange

Optional • Type: (isPresented: boolean) => void

A callback that is called when the isPresented state changes.

title

Type: string

The title of the alert.

Inherited props

Modifiers

Use these modifiers in the modifiers prop of the SwiftUI version.

Expo UI lets you put any of the 89 modifiers for any view on Alert, but not all of them do something here.

  • 74 change what you see on Alert.
  • 2 work, but not in the way that you may expect.
  • 2 have no visible effect on Alert.
  • 13 work only in one place, such as a widget or a Grid.

Where the modifiers go

modifiers apply to the Alert.Trigger view. They do not change the alert, because the system draws it. With no trigger, you see no result.

Best modifiers for Alert

These modifiers are the ones that you use most with Alert.

Also works on Alert

Alert takes these modifiers too, and each one works in the usual way.

Needs care on Alert

These modifiers work on Alert, but not in the way that you may expect.

ModifierWhat to know
onAppearRuns for the trigger, not for the alert.
onDisappearRuns for the trigger, not for the alert.

No visible effect on Alert

Alert accepts these modifiers, but you see no change. They do not give an error.

ModifierWhy nothing happens
layoutPriorityIt has an effect only when the view shares an axis with other views in a stack.
zIndexIt changes the order of views that cover each other in the same parent, and Alert does not stack its children.

Only in some places

These modifiers work only in a widget, in a Grid, in a Namespace or in a parent that asks for them.

ModifierWhere it works
activityBackgroundTintWorks only in a Live Activity. It has no effect in the app.
alignmentGuideHas an effect only when the parent, such as a VStack or ZStack, aligns its children by the same guide.
containerBackgroundWorks only in a widget, or in a navigation container when you use a navigation placement.
glassEffectIdWorks only on a view that also has glassEffect, in a GlassEffectContainer and a Namespace.
gridCellAnchor iOS 16+Works only on a cell of a Grid. Grid is in @expo/ui/swift-ui, but it has no Expo docs page.
gridCellColumnsWorks only on a view in a Grid.Row. Grid is in @expo/ui/swift-ui, but it has no Expo docs page.
gridCellUnsizedAxesWorks only on a view in a Grid. Grid is in @expo/ui/swift-ui, but it has no Expo docs page.
gridColumnAlignment iOS 16+Works only on a view in a Grid.Row. Grid is in @expo/ui/swift-ui, but it has no Expo docs page.
invalidatableContent iOS 17+Has an effect only when a parent view uses redacted with the invalidated reason.
matchedGeometryEffectWorks only in a Namespace. Give two views the same id and change between them with an animation.
privacySensitiveHas an effect only when a parent view uses redacted with the privacy reason.
unredactedHas an effect only in a parent view that uses redacted.
widgetURLWorks only in a widget. It has no effect in the app.

Sources

The original Expo docs for this page:

  • Alert (SwiftUI) (source-of-truth/versions/v57.0.0/sdk/ui/swift-ui/alert.md)

On this page