xcode 在 iphone 的 UIWebView 中显示选择的自定义菜单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2955354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 19:24:34  来源:igfitidea点击:

showing custom menu on selection in UIWebView in iphone

iphoneobjective-cxcodeuiwebviewuimenucontroller

提问by Sagar R. Kothari

I want to show 2 options like "hi" & "bye" when user completes selection on UIWebView.

当用户在 UIWebView 上完成选择时,我想显示 2 个选项,如“hi”和“bye”。

I have added observer to my view controller as follows. But I don't know further implementation.

我已将观察者添加到我的视图控制器中,如下所示。但我不知道进一步的实施。

[[UIMenuController sharedMenuController] addObserver:self 
                                          forKeyPath:UIMenuControllerWillShowMenuNotification
                                             options:nil
                                             context:nil
 ];

回答by Jacques

Sagar,

萨加尔,

Your question is a couple of months old, but I finally figured this one out, so I figured I'd answer it in case it helps out someone else.

你的问题已经有几个月了,但我终于想通了这个问题,所以我想我会回答它,以防它对其他人有帮助。

I added the following code to the viewDidAppear: method of the view controller that contains the webview.

我将以下代码添加到包含 webview 的视图控制器的 viewDidAppear: 方法中。

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    UIMenuItem *customMenuItem1 = [[[UIMenuItem alloc] initWithTitle:@"Custom 1" action:@selector(customAction1:)] autorelease];
    UIMenuItem *customMenuItem2 = [[[UIMenuItem alloc] initWithTitle:@"Custom 2" action:@selector(customAction2:)] autorelease];
    [[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:customMenuItem1, customMenuItem2, nil]];
}

In my viewDidDisappear:, I go ahead and remove those items:

在我的 viewDidDisappear: 中,我继续删除这些项目:

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];

    [[UIMenuController sharedMenuController] setMenuItems:nil];
}

Then, I implemented the canPerformAction:withSender: method in the view controller. It helps to understand the concept of responders and responder chains to understand what is going on here. Basically, your uiviewcontroller is part of the responder chain, so it gets asked if it can handle any actions (like your custom actions you added above) that objects higher up the responder chain (like the UIWebView) don't know how to handle (see the UIResponder documentationand the Event Handling Guide for iOSfor the gory details).

然后,我在视图控制器中实现了 canPerformAction:withSender: 方法。它有助于理解响应者和响应者链的概念,以了解这里发生的事情。基本上,您的 uiviewcontroller 是响应者链的一部分,因此它会被问及它是否可以处理响应者链更高的对象(如 UIWebView)不知道如何处理的任何操作(如您在上面添加的自定义操作)(有关详细信息,请参阅UIResponder 文档iOS 事件处理指南)。

Now, when canPerformAction:withSender: is called for the webview, the sender parameter is set to nil. So, I try to be a bit clever about how I write this function. Basically, I make sure that the sender is nil, I'm showing the webview to the user, and any other controls on the page aren't the first responder. If that's the case, then I check to see if this is one of the actions I defined above and retur YES if it is. In all other cases I return the default value from UIViewController by calling the same method on super.

现在,当为 webview 调用 canPerformAction:withSender: 时,sender 参数设置为 nil。所以,我试着对我如何编写这个函数有点聪明。基本上,我确保发件人为零,我正在向用户显示 webview,并且页面上的任何其他控件都不是第一响应者。如果是这种情况,那么我会检查这是否是我上面定义的操作之一,如果是,则返回 YES。在所有其他情况下,我通过在 super 上调用相同的方法从 UIViewController 返回默认值。

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if (webView.superview != nil && ![urlTextField isFirstResponder]) {
        if (action == @selector(customAction1:) || action == @selector(customAction2:)) {
            return YES;
        }
    }

    return [super canPerformAction:action withSender:sender];
}

Of course, now the next step is figuring out how to actually do something with the selection (probably by running some JavaScript in the webview).

当然,现在下一步是弄清楚如何对选择进行实际操作(可能通过在 webview 中运行一些 JavaScript)。

回答by parag

In swift:

迅速:

class ViewController: UIViewController {
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        // add two custom menu items to the context menu of UIWebView (assuming in contenteditable mode)
        let menuItem1 = UIMenuItem(title: "Foo", action: #selector(ViewController.foo))
        let menuItem2 = UIMenuItem(title: "Bar", action: #selector(ViewController.bar))
        UIMenuController.sharedMenuController().menuItems = [menuItem1, menuItem2]
    }

    override func viewDidDisappear(animated: Bool) {
        super.viewDidAppear(animated)
        UIMenuController.sharedMenuController().menuItems = nil
    }

    override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
        if webView?.superview != nil {
            if action == #selector(ViewController.foo) || action == #selector(ViewController.bar) {
                return true
            }
        }

        return super.canPerformAction(action, withSender: sender)
    }

    func foo() {
        print("foo")
    }

    func bar() {
        print("bar")
    }
}

Note: #selector is available in Swift 2.2.

注意:#selector 在 Swift 2.2 中可用。

screenshot

截屏