Ios 如何以编程方式使文本可选,并提供弹出菜单以转到其他应用程序

Ios 如何以编程方式使文本可选,并提供弹出菜单以转到其他应用程序,ios,uimenucontroller,Ios,Uimenucontroller,我正在尝试在iOS项目中实现一个功能,当您选择一段文本并高亮显示它时,您可以从菜单选项中选择使用另一个应用程序,如默认字典。有可能这样做吗?如果是,我在哪里可以找到这样的文档或教程?您正在描述iOS菜单。查看有关类的文档,如UIMenu、UIMenuItem和UIMenuController。我找到了解决问题的方法。 感谢本文作者: 将自定义菜单项添加到默认菜单控制器 ViewController.h - (void)longPressGestureRecognizer:(UIGestureR

我正在尝试在iOS项目中实现一个功能,当您选择一段文本并高亮显示它时,您可以从菜单选项中选择使用另一个应用程序,如默认字典。有可能这样做吗?如果是,我在哪里可以找到这样的文档或教程?

您正在描述iOS菜单。查看有关类的文档,如UIMenu、UIMenuItem和UIMenuController。

我找到了解决问题的方法。 感谢本文作者:

将自定义菜单项添加到默认菜单控制器

ViewController.h

- (void)longPressGestureRecognizer:(UIGestureRecognizer *)recognizer
{
    UIMenuItem *mi = [self.label menuItemOpenPleco];
    UIMenuController *menuController = [UIMenuController sharedMenuController];
    menuController.menuItems = @[mi];
}
粘贴板标签{h,m}

@interface PasteboardLabel : UILabel

- (UIMenuItem *)menuItemOpenPleco;

@end

@implementation PasteboardLabel

- (UIMenuItem *)menuItemOpenPleco
{
    return [[UIMenuItem alloc] initWithTitle:@"Open Pleco" action:@selector(openPleco:)];
}

- (void)openPleco:(id)sender
{
    NSString *selectedText = [self textInRange:[self selectedTextRange]];
    UIPasteboard *pb = [UIPasteboard generalPasteboard];
    pb.string = selectedText;
    NSString *urlString = [NSString stringWithFormat:@"plecoapi://x-callback-url/q?s=%@", pb.string];
    NSURL *url = [[NSURL alloc] initWithString:urlString];

    [[UIApplication sharedApplication] openURL:url];

}

@end

我发现添加自定义菜单项的例子很少,也没有解释它们是如何工作的。所以我想通过分享一些重要的小道消息然后展示一个例子来解决这个问题

  • UIMenuController
    UIView
    s“对话”,而不是与
    UIViewController
    s“对话”。这意味着您的
    UIMenuController
    相关代码需要进入
    UIView
    的子类,而不是
    UIViewController
  • 注意我前面例子开头的单词the。只有一个
    UIMenuController
    ,一个从应用程序首次启动到结束的单例。这意味着您应该只添加一次项,并且不应该在现有项数组上进行写入
  • ui菜单中按钮的外观取决于点击的
    ui视图是否响应选择器。这意味着,如果希望按钮出现,则需要实现该方法,并且不必担心在点击不相关的视图时按钮会出现,除非您选择了其他UIView也有方法的选择器名称
  • 说到这里,我创建了一个
    UITextView
    的子类(根据我的第一个项目,这意味着它是
    UIView
    的子类),然后我给了它这个
    initialize
    方法,以及选择器的实现

    + (void)initialize {
        static dispatch_once_t addInsert;
        dispatch_once(&addInsert, ^{
            UIMenuController *mController = [UIMenuController sharedMenuController];
            UIMenuItem *insert = [[UIMenuItem alloc] initWithTitle:@"Insert..."
                                                            action:@selector(insert:)];
            mController.menuItems = [mController.menuItems arrayByAddingObject:insert];
        });
    }
    
    - (void)insert:(id)sender {
        NSLog(@"Insert... pressed!");
    }
    
    以上要点如下:

  • 它位于类
    initialize
    方法中,该方法在第一次调用类中的任何其他方法之前由运行时调用。实际上,这意味着代码是在自定义视图的实例第一次出现在屏幕上之前处理的
  • 我在它周围加了一个
    dispatch\u
    guard。如果我的类是子类,那么这些子类可能会调用这个
    initialize
    方法。可能这些子类比这个子类先出现,所以我不想阻止
    initialize
    方法运行。我只是想防止它运行多次。因此,我将代码包装在一次
    dispatch\u
  • 我不仅仅是将
    菜单项设置为一个新的项目数组,而是将其分配给一个新的项目数组,该数组使用我的新项目扩展了现有的项目数组

  • 希望这些都对你有帮助。这并不复杂,你当然可以用其他方法来实现我的第二点——我试图选择一种对我来说似乎最安全的方法,但肯定有更简单的方法。请给出一些有用的建议,而不是发布一般信息的链接。在我提出这个问题之前,我实际上已经阅读了关于文本编程指南的整篇文章。你要求提供文件,所以我提供了文件。2.在你的问题中有两个部分-使文本可选,并提供自定义选项。您可以向我们显示相关代码和/或告诉我们您遇到的问题。@Peng OK谢谢。我将继续在这里发布相关的源代码,以防将来出现问题。到目前为止,您已经尝试了什么?Lazy。请在线查看我的示例,例如在文本字段中选择的示例: