You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何通过长按手势唤起Context Menu与Menu组件?

关于SwiftUI长按唤起菜单的两个问题解答

嘿,这两个场景我都帮你捋清楚,咱们一个个说:

一、长按唤起Context Menu

首先明确告诉你:SwiftUI的contextMenu修饰符默认就是通过长按手势触发的!你写的那段代码其实已经实现了长按唤起上下文菜单的功能,可能你是不是没在真机或正确的模拟器环境测试?我给你调整下代码,让逻辑更清晰:

struct MessageView: View {
    let messageModel: MessageModel
    @State private var isExpanded = false
    @State private var isClientNameVisible = false
    
    var body: some View {
        Text(messageModel.message)
            .padding(.vertical, 8)
            .padding(.horizontal, 12)
            .background(Constants.clientMessageColor)
            .foregroundColor(.black)
            .cornerRadius(20) // 四个角都圆角的话可以简化写法
            .onTapGesture {
                isExpanded.toggle()
                isClientNameVisible.toggle()
            }
            .contextMenu {
                Button(action: {
                    // 这里添加你的"Normal Colors"逻辑
                }) {
                    Text("Normal Colors")
                    Image(systemName: "paintbrush")
                }
                // 还可以扩展更多菜单选项
                Button(action: {}) {
                    Text("Copy Message")
                    Image(systemName: "doc.on.doc")
                }
            }
    }
}

// 假设你的Constants定义
struct Constants {
    static let clientMessageColor = Color.blue.opacity(0.2)
}

只要长按这个Text视图,系统默认就会弹出你定义的上下文菜单,完全不需要额外写长按手势代码哦。

二、长按唤起Menu组件

Menu组件默认是点击触发的,要改成长按唤起的话,我们需要用一个状态变量手动控制菜单的显示/隐藏,结合onLongPressGesture来触发状态变化,具体实现代码如下:

struct CustomMenuView: View {
    @State private var showMenu = false
    
    var body: some View {
        Text("HELLO")
            .onLongPressGesture {
                showMenu = true // 长按触发,打开菜单
            }
            .menu(isPresented: $showMenu) {
                Button("Order Now", action: {
                    // 订单逻辑
                    showMenu = false // 执行完后关闭菜单
                })
                Button("Adjust Order", action: {
                    // 调整订单逻辑
                    showMenu = false
                })
                Button("Cancel", action: {
                    // 取消逻辑
                    showMenu = false
                })
            }
    }
}

这里用menu(isPresented:)这个重载方法,绑定我们的showMenu状态变量,当长按手势触发时把showMenu设为true,菜单就会弹出来;每个按钮执行完逻辑后记得把showMenu设为false来关闭菜单。

这样两个场景就都实现长按唤起菜单的效果啦~

内容的提问来源于stack exchange,提问作者Mactacs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 14:37:46