Reference version

菜单

一个用于显示下拉菜单的 SwiftUI Menu 组件。

iOS
tvOS
Bundled version:
~55.0.0-beta.0

For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.

Expo UI Menu 与官方 SwiftUI Menu API 保持一致,并支持通过 buttonStyle 修饰符进行样式设置。Menu 通过单击打开。对于长按交互,请改用 ContextMenu

Note: 在 tvOS 上,Menu 需要 tvOS 17.0 或更高版本。

安装

Terminal
npx expo install @expo/ui

If you are installing this in an existing React Native app, make sure to install expo in your project.

用法

简单文本标签

SimpleMenuExample.tsx
import { Host, Menu, Button } from '@expo/ui/swift-ui'; export default function SimpleMenuExample() { return ( <Host matchContents> <Menu label="选项"> <Button label="选项 1" onPress={() => console.log('Option 1')} /> <Button label="选项 2" onPress={() => console.log('Option 2')} /> <Button label="选项 3" onPress={() => console.log('Option 3')} /> </Menu> </Host> ); }

带 SF Symbol 的文本标签

MenuWithIconExample.tsx
import { Host, Menu, Button, Divider } from '@expo/ui/swift-ui'; export default function MenuWithIconExample() { return ( <Host matchContents> <Menu label="更多" systemImage="ellipsis.circle"> <Button label="设置" systemImage="gear" onPress={() => console.log('Settings')} /> <Button label="个人资料" systemImage="person" onPress={() => console.log('Profile')} /> <Divider /> <Button label="删除" role="destructive" systemImage="trash" onPress={() => console.log('Delete')} /> </Menu> </Host> ); }

自定义标签

你可以将 React node 作为标签传入,以进行自定义样式设置。

CustomLabelMenuExample.tsx
import { Host, Menu, Button, Text } from '@expo/ui/swift-ui'; export default function CustomLabelMenuExample() { return ( <Host matchContents> <Menu label={<Text color="accentColor">自定义标签</Text>}> <Button label="操作 1" onPress={() => console.log('Action 1')} /> <Button label="操作 2" onPress={() => console.log('Action 2')} /> </Menu> </Host> ); }

嵌套菜单

菜单可以嵌套以创建子菜单。

NestedMenuExample.tsx
import { Host, Menu, Button } from '@expo/ui/swift-ui'; export default function NestedMenuExample() { return ( <Host matchContents> <Menu label="主菜单"> <Button label="项目 1" onPress={() => console.log('Item 1')} /> <Menu label="子菜单"> <Button label="子项目 1" onPress={() => console.log('Sub Item 1')} /> <Button label="子项目 2" onPress={() => console.log('Sub Item 2')} /> </Menu> <Button label="项目 2" onPress={() => console.log('Item 2')} /> </Menu> </Host> ); }

带主要操作

当提供 onPrimaryAction 时,单击会触发主要操作,而长按会显示菜单。

PrimaryActionMenuExample.tsx
import { Host, Menu, Button } from '@expo/ui/swift-ui'; export default function PrimaryActionMenuExample() { return ( <Host matchContents> <Menu label="轻点或按住" systemImage="play.circle" onPrimaryAction={() => console.log('Primary action triggered!')}> <Button label="菜单项 1" onPress={() => console.log('Menu Item 1')} /> <Button label="菜单项 2" onPress={() => console.log('Menu Item 2')} /> <Button label="菜单项 3" onPress={() => console.log('Menu Item 3')} /> </Menu> </Host> ); }

使用修饰符进行样式设置

你可以使用 buttonStyle 修饰符来更改菜单触发器的外观。

StyledMenuExample.tsx
import { Host, Menu, Button } from '@expo/ui/swift-ui'; import { buttonStyle } from '@expo/ui/swift-ui/modifiers'; export default function StyledMenuExample() { return ( <Host matchContents> <Menu label="样式化菜单" modifiers={[buttonStyle('borderedProminent')]}> <Button label="样式化操作 1" onPress={() => console.log('Styled 1')} /> <Button label="样式化操作 2" onPress={() => console.log('Styled 2')} /> </Menu> </Host> ); }

玻璃菜单

要创建具有 iOS Liquid Glass 外观的菜单,请在 Menu 组件上使用 buttonStyle('glass')buttonStyle('glassProminent')

Important: 不要对 Menu 的标签视图应用 glassEffect() 修饰符来实现玻璃效果。这样会导致一种视觉瑕疵:当菜单被关闭时,触发器后方会短暂出现一个矩形光晕。请始终使用 buttonStyle,因为它能正确地与 Menu 的关闭动画集成。

GlassMenuExample.tsx
import { Host, Menu, Button } from '@expo/ui/swift-ui'; import { buttonStyle } from '@expo/ui/swift-ui/modifiers'; export default function GlassMenuExample() { return ( <Host matchContents> <Menu label="玻璃菜单" systemImage="ellipsis.circle" modifiers={[buttonStyle('glass')]}> <Button label="操作 1" onPress={() => console.log('Action 1')} /> <Button label="操作 2" onPress={() => console.log('Action 2')} /> </Menu> </Host> ); }

若要获得更突出的玻璃效果,请使用 glassProminent

GlassProminentMenuExample.tsx
import { Host, Menu, Button } from '@expo/ui/swift-ui'; import { buttonStyle } from '@expo/ui/swift-ui/modifiers'; export default function GlassProminentMenuExample() { return ( <Host matchContents> <Menu label="突出玻璃菜单" systemImage="slider.horizontal.3" modifiers={[buttonStyle('glassProminent')]}> <Button label="设置" systemImage="gear" onPress={() => console.log('Settings')} /> <Button label="筛选" systemImage="line.3.horizontal.decrease" onPress={() => console.log('Filter')} /> </Menu> </Host> ); }

使用控制组

在菜单中使用 ControlGroup 可渲染一行水平排列的图标按钮,类似于 Apple Music 或 Safari 菜单中的快速操作行。

MenuWithControlGroupExample.tsx
import { Host, Menu, ControlGroup, Button, Section, Divider } from '@expo/ui/swift-ui'; export default function MenuWithControlGroupExample() { return ( <Host matchContents> <Menu label="歌曲选项" systemImage="ellipsis.circle"> <ControlGroup> <Button systemImage="plus" label="添加" onPress={() => console.log('Add')} /> <Button systemImage="star" label="收藏" onPress={() => console.log('Favorite')} /> <Button systemImage="square.and.arrow.up" label="分享" onPress={() => console.log('Share')} /> </ControlGroup> <Section> <Button systemImage="text.badge.plus" label="添加到播放列表" onPress={() => console.log('Add to Playlist')} /> <Button systemImage="antenna.radiowaves.left.and.right" label="创建电台" onPress={() => console.log('Create Station')} /> </Section> <Divider /> <Button systemImage="hand.thumbsdown" label="建议少看" onPress={() => console.log('Suggest Less')} /> </Menu> </Host> ); }

仅图标菜单按钮

使用 labelStyle('iconOnly') 修饰符仅显示图标,不显示标签文本。不过出于可访问性考虑,仍应提供 label 属性。

IconOnlyMenuExample.tsx
import { Host, Menu, Button } from '@expo/ui/swift-ui'; import { labelStyle } from '@expo/ui/swift-ui/modifiers'; export default function IconOnlyMenuExample() { return ( <Host matchContents> <Menu label="仅图标按钮" systemImage="gear" modifiers={[labelStyle('iconOnly')]}> <Button label="菜单项 1" onPress={() => console.log('Menu Item 1')} /> <Button label="菜单项 2" onPress={() => console.log('Menu Item 2')} /> <Button label="菜单项 3" onPress={() => console.log('Menu Item 3')} /> </Menu> </Host> ); }

API

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

Component

iOS
tvOS

Type: React.Element<MenuProps>

Displays a dropdown menu when tapped.

Props for the Menu component.

MenuProps

children

iOS
tvOS
Type: ReactNode

The menu's content items, which are shown when the menu is opened. Can contain Button, Toggle, Picker, Section, Divider or nested Menu components.

label

iOS
tvOS
Literal type: union

The label for the menu trigger. Can be a string for simple text labels, or a ReactNode for custom label content.

Acceptable values are: string | ReactNode

onPrimaryAction

iOS
tvOS
Optional • Type: () => void

A callback that is invoked when the user taps the menu label. When provided, a single tap triggers this action, while a long-press shows the menu. When not provided, a single tap shows the menu.

systemImage

iOS
tvOS
Optional • Type: string

An SF Symbol name to display alongside the label. Only used when label is a string.