[Text Relatives II]
When your app determines that the user has requested the edit menu—which could be the action of making a selection—you should complete the following steps to display the menu:
-
Call the
sharedMenuController
class method ofUIMenuController
to get the global menu-controller instance. -
Compute the boundaries of the selection and with the resulting rectangle call the
setTargetRect:inView:
method. The edit menu is displayed above or below this rectangle, depending how close the selection is to the top or bottom of the screen. -
Call the
setMenuVisible:animated:
method (withYES
for both arguments) to animate the display of the edit menu above or below the selection.
Displaying the edit menu:
1 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 2 UITouch *theTouch = [touches anyObject]; 3 4 if ([theTouch tapCount] == 2 && [self becomeFirstResponder]) { 5 6 // selection management code goes here... 7 8 // bring up edit menu. 9 UIMenuController *theMenu = [UIMenuController sharedMenuController]; 10 CGRect selectionRect = CGRectMake (currentSelection.x, currentSelection.y, SIDE, SIDE); 11 [theMenu setTargetRect:selectionRect inView:self]; 12 [theMenu setMenuVisible:YES animated:YES]; 13 14 } 15 }
Before the menu is displayed, however, the system sends a canPerformAction:withSender:
message to the first responder, which in many cases is the custom view itself.
Conditionally enabling menu commands:
1 - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { 2 BOOL retValue = NO; 3 ColorTile *theTile = [self colorTileForOrigin:currentSelection]; 4 5 if (action == @selector(paste:) ) 6 retValue = (theTile == nil) && 7 [[UIPasteboard generalPasteboard] containsPasteboardTypes: 8 [NSArray arrayWithObject:ColorTileUTI]]; 9 else if ( action == @selector(cut:) || action == @selector(copy:) ) 10 retValue = (theTile != nil); 11 else 12 retValue = [super canPerformAction:action withSender:sender]; 13 return retValue; 14 }
Implementing a Change Color menu item:
1 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {} 2 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {} 3 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 4 UITouch *theTouch = [touches anyObject]; 5 if ([theTouch tapCount] == 2) { 6 [self becomeFirstResponder]; 7 UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Change Color" action:@selector(changeColor:)]; 8 UIMenuController *menuCont = [UIMenuController sharedMenuController]; 9 [menuCont setTargetRect:self.frame inView:self.superview]; 10 menuCont.arrowDirection = UIMenuControllerArrowLeft; 11 menuCont.menuItems = [NSArray arrayWithObject:menuItem]; 12 [menuCont setMenuVisible:YES animated:YES]; 13 } 14 } 15 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {} 16 17 - (BOOL)canBecomeFirstResponder { return YES; } 18 19 - (void)changeColor:(id)sender { 20 if ([self.viewColor isEqual:[UIColor blackColor]]) { 21 self.viewColor = [UIColor redColor]; 22 } else { 23 self.viewColor = [UIColor blackColor]; 24 } 25 [self setNeedsDisplay]; 26 }
Dismiss the Edit Menu:
1 [UIMenuController sharedMenuController].menuVisible = YES;