Untitled

 avatar
unknown
plain_text
a month ago
3.9 kB
2
Indexable
struct ContextMenuHelper<Content: View,Preview: View>: UIViewRepresentable{
    
    var content: Content
    var preview: Preview
    var actions: UIMenu
    var onEnd: ()->()
    var onOpen: ()->()
    var onClose: ()->()
    
    init(content: Content,preview: Preview,actions: UIMenu,onEnd: @escaping ()->(),onOpen: @escaping ()->(),onClose: @escaping ()->()){
        self.content = content
        self.preview = preview
        self.actions = actions
        self.onEnd = onEnd
        self.onOpen = onOpen
        self.onClose = onClose
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(parent: self)
    }
    
    func makeUIView(context: Context) -> UIView {
        
        let view = UIView()
        view.backgroundColor = .clear
        
        // setting our content view as Main Interaction view....
        let hostView = UIHostingController(rootView: content)
        
        // setting constraints...
        hostView.view.translatesAutoresizingMaskIntoConstraints = false
        
        // Constarints....
        let constraints = [
            
            hostView.view.topAnchor.constraint(equalTo: view.topAnchor),
            hostView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            hostView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            hostView.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            
            hostView.view.widthAnchor.constraint(equalTo: view.widthAnchor),
            hostView.view.heightAnchor.constraint(equalTo: view.heightAnchor),
        ]
        
        view.addSubview(hostView.view)
        view.addConstraints(constraints)
        view.layer.cornerRadius = 8
        
        // setting interaction...
        let interaction = UIContextMenuInteraction(delegate: context.coordinator)
        
        view.addInteraction(interaction)
        
        
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
 
    }
    
    // COntext Menu Delegate...
    class Coordinator: NSObject,UIContextMenuInteractionDelegate{
        
        var parent: ContextMenuHelper
        init(parent: ContextMenuHelper) {
            self.parent = parent
        }
        
        // Delegate Methods....
        
        func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
            
            return UIContextMenuConfiguration(identifier: nil) {
                
                // your view.....
                let previewController = UIHostingController(rootView: self.parent.preview)
                
                previewController.view.backgroundColor = .clear
                
                return previewController
                
            } actionProvider: { items in
                
                // your actions....
                return self.parent.actions
            }
            
        }
        
        
        func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willDisplayMenuFor configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionAnimating?) {
            self.parent.onOpen()
        }
        
        func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willEndFor configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionAnimating?) {
            self.parent.onClose()
        }
        
        
        // if you need context menu to be expanded...
        func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {
            
            animator.addCompletion {
                self.parent.onEnd()
            }
        }
    }
}
Leave a Comment