SwiftUI 菜单中的内联水平按钮

问题描述 投票:0回答:2

在 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 swift swiftui menu ipados
2个回答
12
投票

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
最多并排放置四个按钮。


5
投票

目前看来此功能仅适用于

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()
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.