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

SwiftUI中如何实现带预览效果的长按上下文菜单?

在SwiftUI中实现带预览与动画的长按上下文菜单

SwiftUI原生ContextMenu不支持顶部预览区域,要实现你需要的带预览+动画的效果,得借助UIKit的UIContextMenuConfiguration来构建,下面是具体实现方案:

1. 构建预览视图

先定义一个用于展示预览内容的SwiftUI视图,可根据需求自定义样式并添加入场动画:

struct ItemPreviewView: View {
    let itemName: String
    @State private var animateIn = false

    var body: some View {
        VStack(spacing: 16) {
            Image(systemName: "star.fill")
                .font(.largeTitle)
                .foregroundColor(.yellow)
                .scaleEffect(animateIn ? 1.2 : 1)
            Text("预览:\(itemName)")
                .font(.title)
                .bold()
                .opacity(animateIn ? 1 : 0)
        }
        .padding()
        .background(Color(.systemGray6))
        .cornerRadius(12)
        .onAppear {
            withAnimation(.spring(response: 0.3, dampingFraction: 0.7)) {
                animateIn = true
            }
        }
    }
}

2. 绑定带预览的上下文菜单

使用.contextMenu(configuration:)修饰符,将UIKit的上下文菜单配置与SwiftUI视图关联,同时设置预览视图和菜单项:

struct ContentView: View {
    let items = ["项目1", "项目2", "项目3"]

    var body: some View {
        List(items, id: \.self) { item in
            Text(item)
                .contextMenu(configuration: {
                    UIContextMenuConfiguration(identifier: nil, previewProvider: {
                        // 将SwiftUI预览视图包装为UIHostingController
                        UIHostingController(rootView: ItemPreviewView(itemName: item))
                    }) { _ in
                        // 构建自定义菜单项
                        UIMenu(title: "", children: [
                            UIAction(title: "编辑", image: UIImage(systemName: "pencil")) { _ in
                                // 此处添加编辑操作逻辑
                            },
                            UIAction(title: "删除", image: UIImage(systemName: "trash"), attributes: .destructive) { _ in
                                // 此处添加删除操作逻辑
                            }
                        ])
                    }
                })
                // 长按触发时的视图缩放动画
                .scaleEffect(0.98)
                .animation(.easeInOut(duration: 0.2), value: UUID())
        }
    }
}

关键细节说明

  • 原生ContextMenu无法添加预览的原因:它封装了UIKit的UIMenu但未暴露预览配置接口,必须通过UIContextMenuConfiguration才能解锁预览功能。
  • 动画定制:预览视图的入场动画可通过SwiftUI的withAnimation实现;若需要更复杂的转场效果,还可实现UIContextMenuInteractionDelegate来修改预览的弹出样式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:05:13