链接预览
编辑
学习如何在使用 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> ); }
自定义链接预览
默认情况下,链接预览呈现为全尺寸页面快照。有几种方法可以自定义此行为。
自定义大小
您可以使用 width 和 height 来建议首选的预览大小。系统将考虑这些首选项,但可能会根据可用空间或平台行为进行覆盖。
<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.Menu 和 Link.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
使用带 asChild 的 Link 时,您只能为 Link.Trigger 指定 一个 child。onPress 事件将仅转发给那个 child。
在预览打开时更改 href
在预览打开时动态更改 href prop 的路径 不支持。您只能动态修改查询参数。