我尝试创建一个自定义 SwiftUI 菜单(基于
UIMenu
)。
但是,我无法触发主要操作。
当我在 CustomMenu
上
点击时它可以工作,但不会触发程序操作。我做错了什么?
struct CustomMenu: UIViewRepresentable {
let title: String
@Binding var isPresented: Bool
func makeUIView(context: Context) -> UIButton {
let button = UIButton(type: .system)
button.setTitle(title, for: .normal)
button.menu = UIMenu(title: "", options: .displayInline, children: [
UIAction(title: "Item 1", image: UIImage(systemName: "mic"), handler: { _ in }),
UIAction(title: "Item 2", image: UIImage(systemName: "envelope"), handler: { _ in }),
UIAction(title: "Item 3", image: UIImage(systemName: "flame.fill"), handler: { _ in }),
UIAction(title: "Item 4", image: UIImage(systemName: "video"), state: .on, handler: { _ in }),
])
button.showsMenuAsPrimaryAction = true
return button
}
func updateUIView(_ uiView: UIButton, context: Context) {
if isPresented {
// neither of .primaryActionTriggered, .menuActionTriggered, .touchUpInside works
uiView.sendActions(for: .primaryActionTriggered)
}
}
}
struct ContentView: View {
@State var menuPresented = false
var body: some View {
VStack {
Button("Show menu programmatically") {
menuPresented = true
}
CustomMenu(title: "Show menu on tap", isPresented: $menuPresented)
.fixedSize()
}
}
}
诀窍是你必须记住,在实践中,
UIMenuElement
实际上是UIAction
。
并记住从“那个按钮”发送操作,这很令人困惑。
苏...
这里,
yourButton
是一个UIButton,您将其用作弹出菜单:
for mc in yourButton.menu?.children ?? [] {
print(" .. actual text of that menu item is", mc.title)
if let solve = mc as? UIAction {
print(solve) // debug info on your Xcode console
solve.performWithSender(yourButton, target: self)
}
}
因此,此代码将按顺序触发每个菜单项作为测试:
for i in 0..<(yourButton.menu.menu?.children ?? []).count {
let mc = (yourButton.menu.menu?.children ?? [])[i]
if let solve = mc as? UIAction {
delay(Double(i) * 1.0) {
print(solve)
solve.performWithSender(self.yourButton.menu, target: self)
}
}
}
就是这样!