【问题标题】:How to disable Copy & Define UIMenuItems of UIMenuController in UITextfield如何在 UITextfield 中禁用 UIMenuController 的复制和定义 UIMenuItems
【发布时间】:2015-01-02 18:58:49
【问题描述】:

我正在实施自定义 UIMenuController 并试图弄清楚。如何在UITextfield 中合法禁用UIMenuController 的“复制”和“定义”UIMenuItems?文本字段不可编辑。我尝试使用以下方法禁用“复制”:

-(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];
}

但菜单仍然显示“复制”和“定义”UIMenuItems。如何禁用它们,只留下我的物品?

【问题讨论】:

    标签: ios objective-c ios8 uimenucontroller uimenuitem


    【解决方案1】:

    最后通过子类化UITextView(为其创建了自定义类)解决了它并添加了

    - (BOOL)canPerformAction:(SEL)action withSender:(id)sender
    {
    
        if (action == @selector(copy:))
        {
            return NO;
        }
    
        return NO;
    }
    

    我的自定义 TextView 子类的 .m 文件内部。

    之后“复制”不再出现,无论有没有[menu update]

    【讨论】:

    • 你是怎么做到的? Xcode 说这是一个私有方法,不能从菜单中删除(实际上它删除了它,但是当我尝试归档项目并将其上传到 appstore 时 - 我就是不能 - 弹出错误并说我使用了 Appe 的私有方法不应该)。
    • 此代码对我不起作用。我在 iOS 9.1、8.3 中尝试过。它仍然支持粘贴选项。请帮助我解决任何其他问题
    【解决方案2】:

    在 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];
    }**
    

    此方法检查目标文本字段是否是第一响应者。如果是,则 NSOperationQueue 为 sharedMenuController 操作创建一个单独的线程,将其可见性和动画设置为 no,使其无法用于复制、粘贴等。 return 语句调用 UIResponder 的 canPerformAction 方法来通知它来实现它。

    【讨论】:

      【解决方案3】:

      Swift 4.2. && Xcode 10 适合我:

      public extension UITextView {
          override 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)
          }
      }
      

      为了完成这项工作,您必须创建 UITextField/UITextView 的子类,并确保在 super.canPerformAction(_:withSender:) 上调用 super!

      【讨论】:

      • 没有子类化是可能的吗?
      • @karthikeyan 是的,应该可以将代码放入扩展中。
      • 你有样品吗?
      • @karthikeyan 如果我理解正确,您想正确禁用所有操作吗?如果是这样,只需将canPerformAction:withSender: 中的代码替换为return false。我的代码只禁用了复制操作。
      【解决方案4】:

      您可以通过继承UITextField 类并覆盖其canPerformAction:: 方法来创建一个类。

      -(BOOL)canPerformAction:(SEL)action withSender:(id)sender
      {
          // Returning 'NO' here disables all actions on textfield
          return NO;
      }
      

      【讨论】:

        猜你喜欢
        • 2018-12-03
        • 2019-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多