How do you REALLY remove Copy from UIMenuController

后端 未结 6 1249
悲&欢浪女
悲&欢浪女 2020-12-04 22:31

There apparently used to be an easy way to prevent the \"More...\" label from appearing in UIMenuController when you added more than one custom menu item. You just had to re

相关标签:
6条回答
  • 2020-12-04 23:04

    The technique you linked to still seems to work. I implemented a UIWebView subclass with these methods, and only the A and B items appeared.

    + (void)initialize
    {
        UIMenuItem *itemA = [[UIMenuItem alloc] initWithTitle:@"A" action:@selector(a:)];
        UIMenuItem *itemB = [[UIMenuItem alloc] initWithTitle:@"B" action:@selector(b:)];
        [[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:itemA, itemB, nil]];
        [itemA release];
        [itemB release];
    }
    
    - (BOOL)canPerformAction:(SEL)action withSender:(id)sender
    {
        BOOL can = [super canPerformAction:action withSender:sender];
        if (action == @selector(a:) || action == @selector(b:))
        {
            can = YES;
        }
        if (action == @selector(copy:))
        {
            can = NO;
        }
        NSLog(@"%@ perform action %@ with sender %@.", can ? @"can" : @"cannot", NSStringFromSelector(action), sender);
        return can;
    }
    
    0 讨论(0)
  • 2020-12-04 23:05

    for ios >= 5.1 canPerformAction:(SEL)action withSender:(id)sender is not working anymore.

    If you are ok with just disable paste action here is a method:

    add UITextFieldDelegate to you view controller and implement method like this

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    if(textField == txtEmailRe)
        return ((string.length) > 1 ? NO : YES);
    }
    

    it means that if user enter more than one character for each action (it means that probably user is pasting something.) do not accept it in textfield.

    it is a good practice for force user enter textfields like e-mail and

    0 讨论(0)
  • 2020-12-04 23:17

    lemnar's answer is correct. Implementing a subclass of UIWebView works just fine. This example is OK for a UITextView. For a UIWebView, create a custom subclass as follows:

    //
    //  MyUIWebView.h
    //
    
    #import <UIKit/UIKit.h>
    
    @interface MyUIWebView : UIWebView
    
    @end
    

    And:

    //
    //  MyUIWebView.m
    //
    
    #import "MyUIWebView.h"
    
    @implementation MyUIWebView
    
    -(BOOL)canPerformAction:(SEL)action withSender:(id)sender 
    {
        if (action == @selector(copy:))
            return NO;
        else
            // logic to show or hide other things
    }
    
    @end
    

    Then, instead of instantiating UIWebView, use MyUIWebView.

    UPDATE:

    If wanting to disable "copy" but leave "define" (and "translate",) which can be useful, this is how to do it; replace canPerformAction:withSender above with this:

    -(BOOL)canPerformAction:(SEL)action withSender:(id)sender 
    {
        if (action == @selector(defineSelection:))
        {
            return YES;
        }
        else if (action == @selector(translateSelection:))
        {
            return YES; 
        }
        else if (action == @selector(copy:))
        {
            return NO;
        }
    
        return [super canPerformAction:action withSender:sender];
    }
    
    0 讨论(0)
  • 2020-12-04 23:18

    I'm sorry for my English. But there is an idea.

    I think the method canPerformAction were called for many times but you just deal with it once. In this case ,I think there may be another UI Control has called it. For example, the UITextView control in your UIWebView.

    I guess you may generate the UI by storyboard. Not every control in storyboard has its own class. You can define a class for the response control and rewrite its canPerformAction method.

    0 讨论(0)
  • 2020-12-04 23:26

    You could draw your own menu instead of using UIMenuController. That way, you can have as many items as you want displayed at the same time without using Other.

    0 讨论(0)
  • 2020-12-04 23:28

    Here is a solution for iOS5.x that works for me. It's by Josh Garnham, suggesting creating a UIWebBrowserView Category to catch the copy:, paste:, define: selectors.

    http://ios-blog.co.uk/iphone-development-tutorials/rich-text-editing-highlighting-and-uimenucontroller-part-3/

    @implementation UIWebBrowserView (UIWebBrowserView_Additions)
    - (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
        return NO;
    }
    @end
    

    Note just FTR: There's a slight typo on that excellent web page. Here's precisely how you do it. Apple will 100% reject this. Make a category

    enter image description here

    (You have to type in "UIWebBrowserView" since Xcode won't bring up private classes.) Full text of the .h and .m files:

    // .h file...
    #import "UIWebBrowserView+Tricky.h"
    @interface UIWebBrowserView : UIView
    @end
    @interface UIWebBrowserView(Tricky)
    @end
    
    // .m file...
    #import "UIWebBrowserView+Tricky.h"
    @implementation UIWebBrowserView (Tricky)
    -(BOOL)canPerformAction:(SEL)action withSender:(id)sender
    {
    NSLog(@"don't let Apple see this");
    return NO;
    }
    @end
    

    For the record, a "single click" will still bring up the annoying spellchecker suggestions! But otherwise it does remove the double-click-context-menu totally, it is 100% rejected by Apple.

    0 讨论(0)
提交回复
热议问题