iOS 14 present UIMenu from UIView
Asked Answered
G

3

8

iOS 14's UIMenu seems to be able to be presented from any UIBarButtonItem or UIButton / UIControl, but I how would I present it from a generic UIView?

Girgenti answered 4/1, 2021 at 18:42 Comment(0)
D
3

Add the interaction:

let interaction = UIContextMenuInteraction(delegate: self)
menuView.addInteraction(interaction)

Add UIContextMenuInteractionDelegate to your controller:

extension YourViewController: UIContextMenuInteractionDelegate {
               
      func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
        return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in
            
            // Create an action for sharing
            let share = UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up")) { action in
                // Show system share sheet
            }
    
            // Create an action for renaming
            let rename = UIAction(title: "Rename", image: UIImage(systemName: "square.and.pencil")) { action in
                // Perform renaming
            }
    
            // Here we specify the "destructive" attribute to show that it’s destructive in nature
            let delete = UIAction(title: "Delete", image: UIImage(systemName: "trash"), attributes: .destructive) { action in
                // Perform delete
            }
    
            // Create and return a UIMenu with all of the actions as children
            return UIMenu(title: "", children: [share, rename, delete])
        }
    }
}

Now, long-press on the view and see your menu :)

More here: https://kylebashour.com/posts/context-menu-guide

Disclosure answered 6/1, 2021 at 18:34 Comment(2)
I apologize if it wasn't fully clear, I'm looking to present the menu from a generic UIView without a long press.Girgenti
@JoelFischer You should update your question with those important details. Otherwise this answer perfectly solves what you asked for in your current question.Roye
O
0

You cannot present a menu directly from a UIView as of now.

The best workaround is to add a UIButton as a subview, and use the UIButton to present the menu. This will work without a long press.

button.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: menuActions)
button.showsMenuAsPrimaryAction = true
view.addSubview(button)
view.sendSubviewToBack(button)
//add necessary constraints to position the button as you please

Note: do not use "UIContextMenuInteraction" with the UIButton or it will require a long press. Thanks to @HangarRash for pointing this out.

Oogenesis answered 1/11, 2023 at 23:24 Comment(0)
D
0

You can add fake transparent UIButton with UIMenu over your view.

UIView * targetView = [ [ UIView alloc ] init ]; // - your view

UIButton * fakeButton = [ [ UIButton alloc ] init ];
fakeButton.showsMenuAsPrimaryAction = YES;
UIAction * action = [ UIAction actionWithTitle:@"Test" image:nil identifier:nil handler:^(__kindof UIAction * _Nonnull action)
{
    //
} ];
fakeButton.menu = [ UIMenu menuWithChildren:[ NSArray arrayWithObject:action ] ];
[ targetView addSubview:fakeButton ];

Don't forget synchronize frame, like

fakeButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

or

fakeButton.frame = targetView.bounds;
Diphenyl answered 2/8 at 21:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.