模态

编辑

学习如何在 Expo Router 中使用模态。


使用模态和 Expo Router
使用模态和 Expo Router

了解各种在您的应用中展示内容的方法。

模态是在移动应用中常见的用户界面模式。它们用于在现有屏幕上展示内容,通常用于不同的目的,例如显示确认警报或独立表单。您可以使用以下方法在应用中创建模态:

  • 使用 React Native 的 Modal 组件。
  • 使用 Expo Router 的特殊文件语法在应用的导航系统中创建模态屏幕。

每种方法都有其特定的使用场景。理解何时使用每种方法对于创造积极的用户体验至关重要。

React Native 的 Modal 组件

Modal 组件是 React Native 核心 API 的一部分。常见用例包括:

  • 独立交互,例如不需要成为导航系统一部分的自包含任务。
  • 临时警报或确认对话框,适合进行快速交互。

下面是一个自定义 Modal 组件的示例,在不同平台上覆盖当前屏幕:

对于大多数用例,您可以使用 Modal 组件并根据应用的用户界面需求进行自定义。有关如何使用 Modal 组件及其属性的详细信息,请参阅 React Native 文档

使用 Expo Router 的模态屏幕

模态屏幕是一个创建在 app 目录中的文件,用作现有堆栈中的路由。它用于需要成为导航系统一部分的复杂交互,例如在多步骤表单中,您可以在过程完成后链接到特定屏幕。

下面是不同平台上模态屏幕工作的示例:

用法

要实现模态路由,请在 app 目录中创建一个名为 modal.tsx 的屏幕。以下是示例文件结构:

app
_layout.tsx
index.tsx
modal.tsx

上述文件结构生成的布局中,index 是堆栈中的第一个路由。在根布局文件 (app/_layout.tsx) 中,您可以在堆栈中添加 modal 路由。要将其呈现为模态,请在路由上将 presentation 选项设置为 modal

app/_layout.tsx
import { Stack } from 'expo-router'; export default function Layout() { return ( <Stack> <Stack.Screen name="index" /> <Stack.Screen name="modal" options={{ presentation: 'modal', }} /> </Stack> ); }

您可以使用 Link 组件从 index.tsx 文件导航到模态屏幕。

app/index.tsx
import { Link } from 'expo-router'; import { StyleSheet, Text, View } from 'react-native'; export default function Home() { return ( <View style={styles.container}> <Text>Home screen</Text> <Link href="/modal" style={styles.link}> Open modal </Link> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', }, link: { paddingTop: 20, fontSize: 20, }, });

modal.tsx 展示模态的内容。

app/modal.tsx
import { StyleSheet, Text, View } from 'react-native'; export default function Modal() { return ( <View style={styles.container}> <Text>Modal screen</Text> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', }, });

模态展示和消失行为

当模态作为导航中的当前屏幕并呈现为独立屏幕时,将失去其先前的上下文。其展示和消失行为在每个平台上都不同:

  • 在 Android 上,模态从当前屏幕上方滑入。要消失它,请使用返回按钮导航回前一个屏幕。
  • 在 iOS 上,模态从当前屏幕底部滑入。要消失它,请从顶部向下滑动。
  • 在网页上,模态作为单独的路由呈现,消失行为必须通过使用 router.canGoBack() 手动提供。以下是如何消失模态的示例:
app/modal.tsx
import { Link, router} from 'expo-router'; import { StyleSheet, Text, View } from 'react-native'; export default function Modal() { const isPresented = router.canGoBack(); return ( <View style={styles.container}> <Text>Modal screen</Text> {isPresented && <Link href="../">关闭模态</Link>} </View> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', }, });

更改 iOS 上状态栏外观

在 iOS 上,模态默认有黑色背景,会隐藏状态栏。要更改状态栏外观,可以使用 Platform API 检查当前平台是否为 iOS,然后使用 StatusBar 组件在 modal.tsx 文件中更改外观。

app/modal.tsx
import { StyleSheet, Text, View, Platform } from 'react-native'; import { StatusBar } from 'expo-status-bar'; export default function Modal() { return ( <View style={styles.container}> <Text>Modal screen</Text> <StatusBar style={Platform.OS === 'ios' ? 'light' : 'auto'} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', }, });

处理深层链接的模态

在使用堆栈或嵌套堆栈导航器时,模态需要锚定以确保正确的导航行为。这在深层链接到模态路由时是必需的。如果不进行锚定,模态后面的屏幕将被擦除,从而没有导航上下文。

一个 作为模态的基础。在复杂的应用中,当您有嵌套堆栈时,锚必须为嵌套堆栈定义,其值成为堆栈的初始路由。

您可以通过从堆栈的布局文件导出 unstable_settings 来配置锚:

export const unstable_settings = { anchor: 'index', // 锚定到索引路由 };

在上述示例中,anchor: 'index' 告诉 Expo Router 在呈现模态时应在后台保持指定的锚点路由。

其他信息

展示选项

通过在 Android 和 iOS 上使用 presentation 选项,有不同的选项可以展示模态屏幕。

选项描述
card新屏幕将被推入堆栈。Android 上的默认动画会根据操作系统版本和主题而有所不同。在 iOS 上,它将从侧面滑入。
modal新屏幕将作为模态呈现,允许在屏幕内呈现嵌套的堆栈。
transparentModal新屏幕将作为模态呈现,之前的屏幕保持可见。如果屏幕有透明背景,内容仍然可以看到。
containedModal在 Android 上,后备到 modal。在 iOS 上,使用 UIModalPresentationCurrentContext 模态样式。
containedTransparentModal在 Android 上,后备到 transparentModal。在 iOS 上,使用 UIModalPresentationOverCurrentContext 模态样式。
fullScreenModal在 Android 上,后备到 modal。在 iOS 上,使用 UIModalPresentationFullScreen 模态样式。
formSheet在 Android 上,后备到 modal。在 iOS 上,使用 UIModalPresentationFormSheet 模态样式。