Swiftui 快捷菜单-菜单实际打开时的操作

Swiftui 快捷菜单-菜单实际打开时的操作,swiftui,menu,haptic-feedback,Swiftui,Menu,Haptic Feedback,我的应用程序中有一个菜单,当菜单打开时(从onTagGestureaction),我会触发触觉反馈 然而有时当我点击菜单打开触发器时,菜单实际上不会打开,但我仍然会得到触觉反馈。我想触觉只有当菜单实际上将打开 下面是代码简化代码块: Menu { Button("Menu button", action: someAction}} } label: { Text("Open menu") //in reality, this a more

我的应用程序中有一个菜单,当菜单打开时(从
onTagGesture
action),我会触发触觉反馈

然而有时当我点击菜单打开触发器时,菜单实际上不会打开,但我仍然会得到触觉反馈。我想触觉只有当菜单实际上将打开

下面是代码简化代码块:

Menu {
    Button("Menu button", action: someAction}}
} label: { 
    Text("Open menu") //in reality, this a more complicated view tapping on which should open the (context) menu
}
.onTagGesture {
  let generator = UIImpactFeedbackGenerator(style: .rigid)
  generator.impactOccurred()
}
所以这是非常简单的-点击
打开菜单
触发器,点击被注册,触觉被回放,菜单打开

但如前所述,无论出于何种原因,有时我按下
打开菜单
元素,触觉会播放,但实际的菜单不会打开

无论原因是什么,我想知道一旦菜单实际打开(或者更好的是,将实际打开),是否有任何方法来执行动作(例如前面提到的触觉反馈)?我试着在任何我能找到的地方搜索,结果一无所获

这一点也很重要,因为菜单也会在长时间点击后打开,这是iOS打开菜单的标准操作。即使我可以为长敲击添加另一个单独的处理程序(为这两种情况提供触觉),这似乎根本不是一个合适的方法

再加上有时候菜单打不开,我确实需要一些其他的解决方案。任何人都可以分享任何想法?是否有某种onXXXXX处理程序我不知道,它会在菜单打开时触发

谢谢

PS:为了提供更多细节,我正在尝试对Apple dev文档中描述的菜单实施这种方法:

作为流程的一部分,我尝试将一个外观处理程序附加到整个菜单以及菜单中的一个单独元素。两者似乎都不起作用

Menu {
    Button("Open in Preview", action: openInPreview)
    Button("Save as PDF", action: saveAsPDF)
        .onAppear { doHaptic() } //only fires once, when menu opens, but not for subsequent appearances
} label: {
    Label("PDF", systemImage: "doc.fill")
}
.onAppear { doHaptic() } //doesn't really as it fires when the menu itself appears on the screen as a child of a parent view.

你可以在appear上使用
onAppear
。在菜单上使用它,只有在菜单出现时才会调用它。例如:

struct ContentView: View {
    
    @State var menuOpen: Bool = false
    
    // Just your button that triggers the menu
    var body: some View {
        Button(action: {
            self.menuOpen.toggle()
        }) {
            if menuOpen {
                MenuView(menuOpen: $menuOpen)
            } else {
                Image(systemName: "folder")
            }
        }
    }
}


struct MenuView: View {
    
    @Binding var menuOpen: Bool
    // the menu view
    var body: some View {
        Rectangle()
            .frame(width: 200, height: 200)
            .foregroundColor(Color.red)
            .overlay(Text("Menu Open").foregroundColor(Color.white))
            .onAppear(perform: self.impactFeedback) // <- Use onAppear on the menu view to trigger it
    }
    
    // if function called it triggers the impact
    private func impactFeedback() {
        let generator = UIImpactFeedbackGenerator(style: .rigid)
        generator.impactOccurred()
        print("triggered impact")
    }
}

struct ContentView:View{
@状态变量menuOpen:Bool=false
//只需按下触发菜单的按钮
var body:一些观点{
按钮(操作:{
self.menuOpen.toggle()
}) {
如果Menoopen{
MenuView(menuOpen:$menuOpen)
}否则{
图像(系统名称:“文件夹”)
}
}
}
}
结构菜单视图:视图{
@绑定变量menuOpen:Bool
//菜单视图
var body:一些观点{
矩形()
.框架(宽:200,高:200)
.foregroundColor(颜色:红色)
.overlay(文本(“菜单打开”).foregroundColor(颜色.白色))

.onAppear(perform:self.impactFeedback)//谢谢,但这不是我试图使用的结构。您提出了一个解决方案,当有一个按钮时,它会依次显示或隐藏子视图。我认为这会很好,因为视图实际上是作为过程的一部分生成和销毁的(并触发
onAppear
)操作。我正在尝试获取实际菜单结构的触觉反馈,如下所述:如果我将onAppear处理程序放在menu()结构本身上,当菜单触发器作为父视图的一部分进入视图时,它只会触发一次。