I am implementing custom UIMenuController
and trying to figure out. How can I legally disable "Copy" and "Define" UIMenuItems of UIMenuController
in UITextfield
? Textfield is not editable. I tried to disable "Copy" using:
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(copy:))
{
return NO;
}
return [super canPerformAction:action withSender:sender];
}
- (IBAction)tapTextViewGesture:(id)sender {
UIMenuItem *myItem1 = [[UIMenuItem alloc] initWithTitle:@"myItem1" action:@selector(myItem1Pressed:)];
UIMenuItem *myItem2 = [[UIMenuItem alloc] initWithTitle:@"myItem2" action:@selector(myItem2Pressed:)];
UIMenuItem *myItem3 = [[UIMenuItem alloc] initWithTitle:@"myItem3" action:@selector(myItem3Pressed:)];
// Access the application's shared menu
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setMenuItems:[NSArray arrayWithObjects:myItem1,myItem2,myItem3, nil]];
CGRect menuRect = CGRectMake(20, 50, 200, 0);
// Show the menu from the cursor's position
[menu setTargetRect:menuRect inView:self.view];
[menu setMenuVisible:YES animated:YES];
}
But the menu is still showing "Copy" and "Define" UIMenuItems
. How can I disable them, leaving only my items?
Finally solved it by subclassing UITextView
(created custom class for it) and just added
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(copy:))
{
return NO;
}
return NO;
}
inside of .m file of my custom TextView subclass.
After that "Copy" doesn't appear any more, with or without [menu update]
;
Implement this instance method in viewController.m:
**- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if ([_targetTextField isFirstResponder]) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO];
}];
}
return [super canPerformAction:action withSender:sender];
}**
This method checks if targeted text field is the first responder or not. If it is, NSOperationQueue creates a separate thread for sharedMenuController operation, set its visibility and animation as no so that it couldn't work for copy, paste,etc. The return statement calls UIResponder's canPerformAction method to inform for the same to implement it.
You can do this by making a class by subclassing UITextField
class and overriding its canPerformAction::
method.
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
// Returning 'NO' here disables all actions on textfield
return NO;
}
Swift 4.2. && Xcode 10 that works for me:
override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
// Requested action to prevent:
guard action != #selector(copy(_:)) else { return false } // disabling copy
// Further actions to prevent:
// guard action != #selector(cut(_:)) else { return false } // disabling cut
// guard action.description != "_share:" else { return false } // disabling share
return super.canPerformAction(action, withSender: sender)
}
In order to make this work you must create a subclass of UITextField
/UITextView
and make sure to call super on super.canPerformAction(_:withSender:)
!
Add this after you set your menu items
[menu update];
I hope this solves your query. :)