在 SwiftUI 中,有一个叫做菜单的东西,其中可以有按钮、分隔符、其他菜单等。下面是我正在构建的一个示例:
import SwiftUI
func testing() {
print("Hello")
}
struct ContentView: View {
var body: some View {
VStack {
Menu {
Button(action: testing) {
Label("Button 1", systemImage: "pencil.tip.crop.circle.badge.plus")
}
Button(action: testing) {
Label("Button 2", systemImage: "doc")
}
}
label: {
Label("", systemImage: "ellipsis.circle")
}
}
}
}
因此,在 SwiftUI Playgrounds 应用程序中,他们有这个菜单:
我的问题是:
他们是如何制作圆形菜单选项的?我在菜单中发现了这组水平按钮的其他一些情况,如下所示:
HStacks 和其他明显的尝试都失败了。我考虑过添加 MenuStyle,但 Apple 的文档非常缺乏,仅显示了向菜单按钮添加红色边框的示例。无论如何,不确定这是正确的道路。
我只能让 Dividers() 和 Buttons() 显示在菜单中:
尽管在应用程序中看到了其他选项的示例,但我也只能找到显示这两个选项的代码示例。
从 iOS 16.4 / macOS 13.3 开始,可以通过在 ControlGroup
中使用
Menu
来完成此操作。
Menu {
ControlGroup {
Button { } label: {
Image(systemName: "1.circle.fill")
}
Button { } label: {
Image(systemName: "2.circle.fill")
}
Button { } label: {
Image(systemName: "3.circle.fill")
}
}
}
.controlGroupStyle
修饰符添加到 ControlGroup
以更改按钮的显示方式。 .menu
是默认样式。您可以使用 .menu
并排放置最多三个按钮,或者使用 .compactMenu
最多并排放置四个按钮。
目前看来此功能仅适用于
UIKit
(且仅限iOS 16+),通过设置
menu.preferredElementSize = .medium
要将其添加到您的应用程序中,您可以将
UIMenu
添加到 UIButton
,然后使用 UIHostingController
将其添加到您的 SwiftUI 应用程序。
这是一个示例实现:
子类化 UIButton
class MenuButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
let inspectAction = self.inspectAction()
let duplicateAction = self.duplicateAction()
let deleteAction = self.deleteAction()
setImage(UIImage(systemName: "ellipsis.circle"), for: .normal)
menu = UIMenu(title: "", children: [inspectAction, duplicateAction, deleteAction])
menu?.preferredElementSize = .medium
showsMenuAsPrimaryAction = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func inspectAction() -> UIAction {
UIAction(title: "Inspect",
image: UIImage(systemName: "arrow.up.square")) { action in
//
}
}
func duplicateAction() -> UIAction {
UIAction(title: "Duplicate",
image: UIImage(systemName: "plus.square.on.square")) { action in
//
}
}
func deleteAction() -> UIAction {
UIAction(title: "Delete",
image: UIImage(systemName: "trash"),
attributes: .destructive) { action in
//
}
}
}
使用 UIViewRepresentable
创建一个Menu
struct Menu: UIViewRepresentable {
func makeUIView(context: Context) -> MenuButton {
MenuButton(frame: .zero)
}
func updateUIView(_ uiView: MenuButton, context: Context) {
}
}
就像魅力一样!
struct ContentView: View {
var body: some View {
Menu()
}
}