A Simple Custom View That Supports UIMenuController on iOS

UIMenuController is the class you interact with to present the pop up menu most commonly used for copy and paste in iOS. I Recently found that while adding a menu to a UIView subclass was easy, it was -- at least for me -- not entirely obvious right away from the documentation. Hopefully this extremely simple example will be useful to someone as they look to add UIMenuController support to their own custom views:

// CopyMeView.h
#import <UIKit/UIKit.h>

@interface CopyMeView : UIView
@end

// CopyMeView.m
#import "CopyMeView.h"

@interface CopyMeView ()
@property (nonatomic, strong) UILabel *label;
@end

@implementation CopyMeView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _label = [[UILabel alloc] initWithFrame:self.bounds];
        _label.textAlignment = NSTextAlignmentCenter;
        _label.text = @"Copy me!"

        [self addSubview:_label];

        UILongPressGestureRecognizer *gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(showMenu:)];
        [self addGestureRecognizer:gestureRecognizer];
    }
    return self;
}

- (CGRect)targetRect
{
    return CGRectMake(self.label.center.x, self.label.center.y, 0.0, 0.0);
}

- (void)showMenu:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
        [self becomeFirstResponder];

        UIMenuController *menu = [UIMenuController sharedMenuController];
        [menu setTargetRect:[self targetRect] inView:self];
        [menu setMenuVisible:YES animated:YES];
    }
}

- (void)copy:(id)sender
{
    [[UIPasteboard generalPasteboard] setString:self.label.text];
}

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

@end

All There Is to It

The important part is that your UIView subclass can become first responder and is so before you present the menu. The menu controller will then look to the first responder to see if it implements any of the standard edit action methods, in our case here we're only implementing the copy method, in order to decide what menu items to present. You can of course implement whatever methods in the UIResponderStandardEditActions protocol that make sense for your class or even add your own menu items to present custom menu options.

Update

It turns out that calling [self resignFirstResponder] as I was doing previously from the edit action method will cause problems if the Speak Selection accessibility feature is enabled. I've updated the sample above accordingly.

"A Simple Custom View That Supports UIMenuController on iOS" was originally published on 23 Apr 2013.