- Touches
- Recipe: Adding a Simple Direct Manipulation Interface
- Recipe: Adding Pan Gesture Recognizers
- Recipe: Using Multiple Gesture Recognizers Simultaneously
- Recipe: Constraining Movement
- Recipe: Testing Touches
- Recipe: Testing Against a Bitmap
- Recipe: Drawing Touches Onscreen
- Recipe: Smoothing Drawings
- Recipe: Using Multi-Touch Interaction
- Recipe: Detecting Circles
- Recipe: Creating a Custom Gesture Recognizer
- Recipe: Dragging from a Scroll View
- Recipe: Live Touch Feedback
- Recipe: Adding Menus to Views
- Summary
Recipe: Adding Menus to Views
The UIMenuController class allows you to add pop-up menus to any item that acts as a first responder. Normally menus are used with text views and text fields, enabling users to select, copy, and paste. Menus also provide a way to add actions to interactive elements like the small drag views used throughout this chapter. Figure 1-6 shows a customized menu. In Recipe 1-14, this menu is presented after long-tapping a flower. The actions will zoom, rotate, or hide the associated drag view.
Figure 1-6 Contextual pop-up menus allow you to add interactive actions to first responder views.
This recipe demonstrates how to retrieve the shared menu controller and assign items to it. Set the menu’s target rectangle (typically the bounds of the view that presents it), adjust the menu’s arrow direction, and update the menu with your changes. The menu can now be set to visible.
Menu items work with standard target-action callbacks, but you do not assign the target directly. Their target is always the first responder view. This recipe omits a canPerformAction:withSender: responder check, but you’ll want to add that if some views support certain actions and other views do not. With menus, that support is often tied to the state. For example, you don’t want to offer a copy command if the view has no content to copy.
Recipe 1-14 Adding Menus to Interactive Views
- (BOOL)canBecomeFirstResponder { // Menus only work with first responders return YES; } - (void)pressed:(UILongPressGestureRecognizer *)recognizer { if (![self becomeFirstResponder]) { NSLog(@"Could not become first responder"); return; } UIMenuController *menu = [UIMenuController sharedMenuController]; UIMenuItem *pop = [[UIMenuItem alloc] initWithTitle:@"Pop" action:@selector(popSelf)]; UIMenuItem *rotate = [[UIMenuItem alloc] initWithTitle:@"Rotate" action:@selector(rotateSelf)]; UIMenuItem *ghost = [[UIMenuItem alloc] initWithTitle:@"Ghost" action:@selector(ghostSelf)]; [menu setMenuItems:@[pop, rotate, ghost]]; [menu setTargetRect:self.bounds inView:self]; menu.arrowDirection = UIMenuControllerArrowDown; [menu update]; [menu setMenuVisible:YES]; } - (instancetype)initWithImage:(UIImage *)anImage { self = [super initWithImage:anImage]; if (self) { self.userInteractionEnabled = YES; UILongPressGestureRecognizer *pressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pressed:)]; [self addGestureRecognizer:pressRecognizer]; } return self; }