如何以编程方式使文本可选择并提供弹出菜单转到另一个应用程序

时间:2014-07-02 02:46:24

标签: ios uimenucontroller

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

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

我找到了解决问题的方法。 感谢本文作者: http://blog.studiovillegas.com/2014/02/06/ios-uipasteboard-uimenucontroller-and-uimenuitem/

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

<强> ViewController.h

- (void)longPressGestureRecognizer:(UIGestureRecognizer *)recognizer
{
    UIMenuItem *mi = [self.label menuItemOpenPleco];
    UIMenuController *menuController = [UIMenuController sharedMenuController];
    menuController.menuItems = @[mi];
}

PasteboardLabel {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

答案 2 :(得分:0)

我发现添加自定义菜单项或解释其工作方式的例子很少。所以我想通过分享一些重要的花絮然后展示一个例子来解决这个问题。

  1. UIMenuController&#34;会谈&#34;使用UIView s,而不是UIViewController s。这意味着您的UIMenuController相关代码需要进入UIView的子类而不是UIViewController
  2. 请注意我之前示例开头的 一词。只有一个UIMenuController,一个单例,从您的应用程序首次启动到结束时共享。这意味着您应该只添加一次项目,并且不应该在现有的项目数组上进行书写。
  3. UIMenu中按钮的外观取决于被点按的UIView是否响应选择器。这意味着,如果您希望按钮显示,则需要实现该方法,并且除非您选择其他UIViews也有方法的选择器名称,否则您不必担心在查看不相关的视图时它会出现。< / LI>

    所以,说了这么多,我创建了一个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!");
    }
    

    以上重点:

    1. 它位于类initialize方法中,该方法在第一次调用类中的任何其他方法之前由运行时调用。实际上,这意味着代码是在第一次自定义视图的实例出现在屏幕上之前处理的。
    2. 我在其周围添加了dispatch_once警卫。如果我的类是子类,那么这些子类可能会调用此initialize方法。也许这些子类出现在这个子类之前,所以我不想阻止initialize方法运行。我只是想阻止它多次运行。这就是为什么我将代码包装在dispatch_once
    3. 我没有将menuItems设置为新的项目数组 - 我将其分配给新项目数组,这些项目使用我的新项目扩展现有项目数组。
    4. 希望你能找到所有有用的东西。它并不是很复杂,你当然可以用其他方式来实现我的第二点 - 我试图选择一种对我来说最安全的方式,但肯定有更简单的方法。