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.