Issue #818

There’s a lot to do to imitate iOS ContextMenu look and feel

  • vibrancy blur background
  • haptics feedback
  • targeted view position
  • interaction dismiss gesture

For now here’s a rough implementation of a custom context menu where we can show using .overlay

import SwiftUI

struct CustomContextMenu<Content: View>: View {
    @Binding var shows: Bool
    @ViewBuilder let content: Content

    var body: some View {
        ZStack {
            Color.black.opacity(0.1)
                .onTapGesture {
                    shows = false
                }

            VStack(alignment: .trailing) {
                Spacer()
                VStack(alignment: .trailing) {
                    content
                }
                .padding(.trailing, 16)
                .padding(.bottom, 90)
                .frame(maxWidth: .infinity, alignment: .trailing)
                .modifier(
                    SwipeToDismissModifier(
                        onDismiss: { shows = false }
                    )
                )
            }
        }
        .background(
            ZStack {
                ClearFullScreenCoverWithBlur()
                VisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial))
            }
        )
        .ignoresSafeArea()
        .transition(AnyTransition.opacity.animation(.easeOut))
    }
}

private struct ClearFullScreenCoverWithBlur: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        DispatchQueue.main.async {
            view.superview?.superview?.backgroundColor = .clear
        }
        return view
    }

    func updateUIView(_ uiView: UIView, context: Context) {}
}