Iphone 在UIWebView中拦截复制、粘贴、定义popover

Iphone 在UIWebView中拦截复制、粘贴、定义popover,iphone,objective-c,ios,ipad,uiwebview,Iphone,Objective C,Ios,Ipad,Uiwebview,当我们在UIWebView中高亮显示文本时,通常是复制、粘贴、定义。。等出现。我如何拦截它,以便在选择复制时调用其他方法/执行其他操作。这可能吗?您可以简单地覆盖-复制: - (void)copy:(id)sender { // Do something else here return [super copy:sender]; } 编辑以回答您的评论。 定义有点棘手,因为它是私有的。但是,您可以实现自己的方法。使用所需项目设置UIMenuController UIMenuIt

当我们在UIWebView中高亮显示文本时,通常是复制、粘贴、定义。。等出现。我如何拦截它,以便在选择复制时调用其他方法/执行其他操作。这可能吗?

您可以简单地覆盖-复制:

- (void)copy:(id)sender
{
    // Do something else here
    return [super copy:sender];
}
编辑以回答您的评论。

定义有点棘手,因为它是私有的。但是,您可以实现自己的方法。使用所需项目设置UIMenuController

UIMenuItem *copyItem = [[UIMenuItem alloc] initWithTitle:@"Copy" 
                                                  action:@selector(myCopy:)];

UIMenuItem *defineItem = [[UIMenuItem alloc] initWithTitle:@"Define"
                                                    action:@selector(myDefine:)];

[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:defineItem, copyItem, nil]];
[defineItem release];
[copyItem release];
然后实现这些方法

至于定义,要复杂得多。。首先,您需要通过覆盖-canPerformAction:withSender:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender 
{
    if (action == @selector(myDefine:)) {
        // Make sure we are on iOS5.x
        if (NSClassFromString(@"UIReferenceLibraryViewController")) {
            return [UIReferenceLibraryViewController dictionaryHasDefinitionForTerm:[webView selectedText]];
        }
    }
    // Implement other custom actions here
    return NO;
}
-selectedText是UIWebView上的一个类别:

- (NSString *)selectedText {
    return [self stringByEvaluatingJavaScriptFromString:@"window.getSelection().toString()"];
}
然后您需要实现myDefine:

- (void)myDefine:(UIMenuController *)menuController 
{    
    CGRect selectedWordFrame = [webView rectForSelectedText];

    UIReferenceLibraryViewController *dict = [[UIReferenceLibraryViewController alloc] initWithTerm:[webView selectedText]];
    UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:dict];
    [popover presentPopoverFromRect:selectedWordFrame
                             inView:webView
           permittedArrowDirections:UIPopoverArrowDirectionAny
                           animated:YES];
    [popover setDelegate:self];
    [dict release];
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController 
{
    [popoverController release];
}
编辑以再次回答您的评论

-rectForSelectedText是UIWebView上的另一个自定义类别

- (CGRect)rectForSelectedText {
    return CGRectFromString([self stringByEvaluatingJavaScriptFromString:@"getRectForSelectedWord()"]);
}
它所做的是调用一个javascript,该javascript返回一个字符串,您可以使用CGRectFromString()转换该字符串,如下所示:

function getRectForSelectedWord() {
    var selection = window.getSelection();
    var range = selection.getRangeAt(0);
    var rect = range.getBoundingClientRect();
    return "{{" + rect.left + "," + rect.top + "}, {" + rect.width + "," + rect.height + "}}";
}

检查以了解如何将javascript注入UIWebView。

哦,顺便说一句,这是在iPhone上,所以当我尝试它时,它会在不在UIUserInterfaceIDiomPad下运行时给我调用。此外,尝试这会给我三个菜单弹出框,复制、定义、定义右键,您应该在-canPerformAction中返回NO:withSender.returning NO会给我相同的结果,只剩下一个问题,那就是如何删除弹出窗口中的define菜单,所以我只有一个define,即mine@adit您是否从响应者链中的任何其他方法返回YES?Apple关于canPerformAction:withSender的说明:请注意,如果您的类对命令返回“否”,则响应程序链上的另一个响应程序仍可能返回“是”,从而启用该命令。下面是一个示例:
- (CGRect)rectForSelectedText {
    return CGRectFromString([self stringByEvaluatingJavaScriptFromString:@"getRectForSelectedWord()"]);
}