UIMenuController
Mobile usability today is truly quite remarkable—especially considering how far it’s come in just the last decade. What was once a clumsy technology relegated to the tech elite has now become the primary mode of computation for a significant portion of the general population.
Yet despite its advances, one can’t help but feel occasionally… trapped.
All too often, there will be information on the screen that you just can’t access. Whether its flight information stuck in a table view cell or an unlinked URL, users are forced to solve problems creatively for lack of a provided solution.
In the past, we’ve mentioned localization and accessibility as two factors that distinguish great apps from the rest of the pack. This week, we’ll add another item to that list: Edit Actions.
Copy, Cut, Paste, Delete, Select
iOS 3’s killer feature was undoubtedly push notifications, but the ability to copy-paste is probably a close second. For how much we use it everyday, it’s difficult to imagine how we got along without it. And yet, it remains a relatively obscure feature for 3rd-party apps.
This may be due to how cumbersome it is to implement. Let’s look at a simple implementation, and then dive into some specifics about the APIs. First the label itself:
class Hipster Label : UILabel {
    override func can Become First Responder() -> Bool {
        return true
    }
    
    override func can Perform Action(action: Selector, with Sender sender: Any Object?) -> Bool {
        return (action == "copy:")
    }
    
    // MARK: - UIResponder Standard Edit Actions
    override func copy(sender: Any Object?) {
        UIPasteboard.general Pasteboard().string = text
    }    
}
                // Hipster Label.h
@interface Hipster Label : UILabel
@end
// Hipster Label.m
@implementation Hipster Label
- (BOOL)can Become First Responder {
    return YES;
}
- (BOOL)can Perform Action:(SEL)action
              with Sender:(id)sender
{
    return (action == @selector(copy:));
}
#pragma mark - UIResponder Standard Edit Actions
- (void)copy:(id)sender {
   	[[UIPasteboard general Pasteboard] set String:self.text];
}
@end
              And with that out of the way, the view controller that uses it:
override func view Did Load() {
	super.view Did Load()
	
	let label: Hipster Label = ...
	label.user Interaction Enabled = true
	view.add Subview(label)
	let gesture Recognizer = UILong Press Gesture Recognizer(target: self, action: "handle Long Press Gesture:")
	label.add Gesture Recognizer(gesture Recognizer)
}
// MARK: - UIGesture Recognizer
func handle Long Press Gesture(recognizer: UIGesture Recognizer) {
	if let recognizer View = recognizer.view,
		recognizer Super View = recognizer View.superview
	{
		let menu Controller = UIMenu Controller.shared Menu Controller()
		menu Controller.set Target Rect(recognizer View.frame, in View: recognizer Super View)
		menu Controller.set Menu Visible(true, animated:true)
		recognizer View.become First Responder()
	}
}
                - (void)view Did Load {
	Hipster Label *label = ...;
	label.user Interaction Enabled = YES;
    [self.view add Subview:label];
    UIGesture Recognizer *gesture Recognizer = [[UILong Press Gesture Recognizer alloc] init With Target:self action:@selector(handle Long Press Gesture:)];
    [label add Gesture Recognizer:gesture Recognizer];
}
#pragma mark - UIGesture Recognizer
- (void)handle Long Press Gesture:(UIGesture Recognizer *)recognizer  {
    if (recognizer.state == UIGesture Recognizer State Recognized) {
        [recognizer.view become First Responder];
        UIMenu Controller *menu Controller = [UIMenu Controller shared Menu Controller];
        [menu Controller set Target Rect:recognizer.view.frame in View:recognizer.view.superview];
        [menu Controller set Menu Visible:YES animated:YES];
    }
}
              So, to recap, in order to allow a label’s text to be copied, the following must happen:
- 
                  
UILabelmust be subclassed to implementcan&Become First Responder canPerform Action:with Sender:  - Each performable action must implement a corresponding method that interacts with 
UIPasteboard - When instantiated by a controller, the label must have 
userset toInteraction Enabled YES(it is not recommended that this be hard-coded into the subclass implementation) - A 
UIGesturemust be added to the label (else,Recognizer UIRespondermethods liketouchesare implemented manually in the subclass)Began:with Event:  - In the method implementation corresponding to the gesture recognizer action, 
UIMenumust be positioned and made visibleController  - Finally, the label must become first responder
 
If you’re wondering why, oh why, this isn’t just built into UILabel, well… join the club.
  UIMenu Controller
UIMenu is responsible for presenting edit action menu items. Each app has its own singleton instance, shared. By default, a menu controller will show commands for any methods in the UIResponder informal protocol that the responder returns YES for in can.
  UIResponder Standard Edit Actions
Handling Copy, Cut, Delete, and Paste Commands
Each command travels from the first responder up the responder chain until it is handled; it is ignored if no responder handles it. If a responder doesn’t handle the command in the current context, it should pass it to the next responder.
copy:This method is invoked when the user taps the Copy command of the editing menu. A subclass of UIResponder typically implements this method. Using the methods of the UIPasteboard class, it should convert the selection into an appropriate object (if necessary) and write that object to a pasteboard.
cut:This method is invoked when the user taps the Cut command of the editing menu. A subclass of UIResponder typically implements this method. Using the methods of the UIPasteboard class, it should convert the selection into an appropriate object (if necessary) and write that object to a pasteboard. It should also remove the selected object from the user interface and, if applicable, from the application’s data model.
delete:This method is invoked when the user taps the Delete command of the editing menu. A subclass of UIResponder typically implements this method by removing the selected object from the user interface and, if applicable, from the application’s data model. It should not write any data to the pasteboard.
paste:This method is invoked when the user taps the Paste command of the editing menu. A subclass of UIResponder typically implements this method. Using the methods of the UIPasteboard class, it should read the data in the pasteboard, convert the data into an appropriate internal representation (if necessary), and display it in the user interface.
Handling Selection Commands
select:This method is invoked when the user taps the Select command of the editing menu. This command is used for targeted selection of items in the receiving view that can be broken up into chunks. This could be, for example, words in a text view. Another example might be a view that puts lists of visible objects in multiple groups; the select: command could be implemented to select all the items in the same group as the currently selected item.
selectThis method is invoked when the user taps the Select All command of the editing menu.All: 
In addition to these basic editing commands, there are commands that deal with rich text editing (toggle, toggle, and toggle) and writing direction changes (make & make). As these are not generally applicable outside of writing an editor, we’ll just mention them in passing.
  UIMenu Item
With iOS 3.2, developers could now add their own commands to the menu controller. As yet unmentioned, but familiar commands like “Define” or spell check suggestions take advantage of this.
UIMenu has a menu property, which is an NSArray of UIMenu objects. Each UIMenu object has a title and action. In order to have a menu item command display in a menu controller, the responder must implement the corresponding selector.
Just as a skilled coder designs software to be flexible and adaptable to unforeseen use cases, any app developer worth their salt understands the need to accommodate users with different needs from themselves.
As you develop your app, take to heart the following guidelines:
- For every control, think about what you would expect a right-click (control-click) to do if used from the desktop.
 - Any time information is shown to the user, consider whether it should be copyable.
 - With formatted or multi-faceted information, consider whether multiple kinds of copy commands are appropriate.
 - When implementing 
copy:make sure to copy only valuable information to the pasteboard. - For editable controls, ensure that your implementation 
paste:can handle a wide range of valid and invalid input. 
If mobile is to become most things to most people, the least we can do is make our best effort to allow users to be more productive. Your thoughtful use of UIMenu will not go unnoticed.