使用 SwiftUI 中的 Menu 组件添加点击菜单
了解如何使用 SwiftUI 中的 Menu 组件为你的 iOS 应用添加点击菜单,并自定义创建不同的菜单效果。
在应用开发过程中,往往需要为界面中的元素添加菜单选项,以便提供更多的操作和交互方式。在此之前,开发者通常需要通过自定义视图或使用多个 UIKit 组件来实现这些功能。
自 iOS 14 开始,SwiftUI 引入了专门的 Menu
组件,简化了这一功能的实现。
Menu 和 ContextMenu 区别
SwiftUI 中提供了两种菜单组件——Menu
和 ContextMenu
。他们最明显的区别是:Menu
组件通过点击触发,ContextMenu
则通过长按触发。
适合 Menu 的使用场景:
- 工具栏中的操作选项:当用户在导航栏或工具栏中需要一组操作时,可以用
Menu
来展示多项选择。 - 按钮上的操作:例如在应用的某个视图上有一个“更多”按钮,点击这个按钮后会弹出多个操作选项,这种情况下适合使用
Menu
。
适合 ContextMenu 的使用场景
ContextMenu
适合用于“上下文菜单”场景,即针对某个特定元素或视图的操作。
- 文件管理应用中的操作:当用户长按某个文件或照片时,可以显示“复制”“删除”“分享”等选项。
- 列表项的操作:在列表应用中,当用户长按一个列表项时,
ContextMenu
可显示对该项的操作,如“标记为已读”“标记为重要”等。
特性 | Menu |
ContextMenu |
---|---|---|
触发方式 | 点击触发 | 长按(iOS)/右键(macOS)触发 |
操作对象 | 通常是一般性的操作或导航栏按钮的操作 | 针对特定视图的上下文操作 |
嵌套支持 | 支持嵌套菜单,适合多级操作 | 不支持嵌套,操作通常简单直接 |
适用场景 | 工具栏菜单、分组操作 | 文件操作、上下文敏感的功能 |
Menu 组件基本用法
首先,让我们来看看如何创建一个最基本的 Menu
组件。
import SwiftUI
struct DocumentMenu: View {
var body: some View {
Menu {
Button(action: {
// 导出 PDF 操作
}) {
Label("导出为 PDF", systemImage: "doc.fill")
}
Button(action: {
// 打印操作
}) {
Label("打印文档", systemImage: "printer")
}
Divider()
Button(
role: .destructive,
action: {
// 删除操作
}
) {
Label("删除文档", systemImage: "trash")
}
} label: {
Image(systemName: "ellipsis.circle")
.font(.title2)
}
}
}
#Preview {
DocumentMenu()
.previewLayout(.sizeThatFits)
.padding()
}
由于 Ghost 平台对图片压缩的原因,导致上述 GIF 动图中 Menu 菜单背景框显示异常,实际上的效果如下:
单独使用 Label 组件时,图标默认在文字左侧显示。不过在 Menu 中使用 Label 组件,图标会被调整到文字右侧显示。
创建 Menu 创建嵌套菜单
有时,一个菜单项可能包含多个子项,这时可以使用嵌套的 Menu
。