链接预览

编辑

学习如何在使用 Expo Router 时,在 iOS 上为链接添加预览。


链接预览是仅适用于 iOS 的功能,仅在 SDK 54 及更高版本中可用。

链接预览(也称为“窥视和弹出”)是 iOS 上常用的功能,用于向用户显示链接屏幕的预览弹出窗口。 本指南将向您展示如何为您的 iOS 应用添加和自定义链接预览。

如果您的应用中有链接,您可以通过用 Link.Trigger 替换链接的内容,并添加 Link.Preview 组件来为其添加链接预览。这将创建一个链接指向页面的预览。

import { Link } from 'expo-router'; export default function Page() { return ( <Link href="/about"> <Link.Trigger>About</Link.Trigger> <Link.Preview /> </Link> ); }

自定义链接预览

默认情况下,链接预览呈现为全尺寸页面快照。有几种方法可以自定义此行为。

自定义大小

您可以使用 widthheight 来建议首选的预览大小。系统将考虑这些首选项,但可能会根据可用空间或平台行为进行覆盖。

<Link href="..."> <Link.Trigger>Content</Link.Trigger> <Link.Preview style={{ width: 300, height: 200 }} /> </Link>

以下示例展示了在 iOS 上自定义链接预览大小:

自定义预览

如果您不想显示默认预览,可以通过 children 向 Link.Preview 组件传递自定义内容。这些自定义内容将替代链接目标的默认预览。

export default function Page() { const [imageSize, setImageSize] = useState({ width: 0, height: 0 }); const { width } = useWindowDimensions(); const previewHeight = (width / imageSize.width) * imageSize.height; return ( <Link href="/about"> <Link.Trigger>About</Link.Trigger> <Link.Trigger>Content</Link.Trigger> <Link.Preview style={{ width, height: previewHeight }}> <Image onLoad={e => setImageSize(e.nativeEvent.source)} source={source} style={{ width: '100%', height: '100%' }} /> </Link.Preview> </Link> ); }

以下示例展示了在 iOS 上的自定义链接预览:

菜单

要在预览旁边渲染上下文菜单,请添加一个 Link.MenuLink.MenuAction children。

<Link href="/about"> <Link.Trigger>About</Link.Trigger> <Link.Menu> <Link.MenuAction title="Share" icon="square.and.arrow.up" onPress={handleSharePress} /> <Link.MenuAction title="Block" icon="nosign" destructive onPress={handleBlockPress} /> </Link.Menu> </Link>

以下示例展示了在 iOS 上的自定义链接预览:

图标

您可以为每个菜单操作指定一个图标,使用 SF Symbols

<Link href="/about"> <Link.Trigger>About</Link.Trigger> <Link.Menu> <Link.MenuAction title="Share" icon="square.and.arrow.up" onPress={handleSharePress} /> <Link.MenuAction title="Block" icon="nosign" onPress={handleBlockPress} /> <Link.MenuAction title="Follow" icon="person.crop.circle.badge.plus" onPress={handleFollowPress} /> <Link.MenuAction title="Copy" icon="doc.on.doc" onPress={handleCopyPress} /> </Link.Menu> </Link>

以下示例展示了具有四个元素的上下文菜单,每个元素使用不同的图标在 iOS 上:

嵌套菜单

您可以通过将一个 Link.Menu 放置在另一个菜单内来嵌套菜单:

<Link href="..."> <Link.Trigger>About</Link.Trigger> <Link.Menu> <Link.MenuAction title="Share" icon="square.and.arrow.up" onPress={() => {}} /> <Link.Menu title="More" icon="ellipsis"> <Link.MenuAction title="Copy" icon="doc.on.doc" onPress={() => {}} /> <Link.MenuAction title="Delete" icon="trash" destructive onPress={() => {}} /> </Link.Menu> </Link.Menu> </Link>

以下示例展示了在 iOS 上的嵌套上下文菜单:

更多自定义选项

要查看更多可用的自定义选项,请参阅 Link.MenuAction 的 API 文档。

检测组件是否在预览中

如果您正在构建一个可能在预览中呈现的组件,您可以使用 useIsPreview() hook 来相应调整其行为:

function MyComponent() { // 如果组件/屏幕在预览中被渲染,则为 true const isInsidePreview = useIsPreview(); return isInsidePreview ? <Text>From within preview</Text> : <Text>I am outside of preview</Text>; }

已知限制

不支持 replace

使用链接预览与 replace 模式当前 不支持。预览只能与默认 push 导航模式一起使用。

JavaScript 标签和插槽

在 JavaScript 标签(而非原生标签)或 Slot 中进行导航时,预览过渡动画可能会显得不够流畅。这是由于 React 的渲染延迟,而原生预览动画会立即开始。为避免此问题,请使用原生标签和堆栈导航器。

缺失 Link.Trigger

如果您渲染一个具有预览或上下文菜单的 Link,但没有 Link.Trigger,将抛出异常。如果在使用预览模式时,将任何非 Link.* 组件直接放置在 Link 内部,也会出现相同的情况。

多个带 asChild 属性的 Link.Trigger children

使用带 asChildLink 时,您只能为 Link.Trigger 指定 一个 child。onPress 事件将仅转发给那个 child。

在预览打开时更改 href

在预览打开时动态更改 href prop 的路径 不支持。您只能动态修改查询参数。