2

我已向 UIMenuController 添加了自定义操作。单击该操作时,我希望弹出窗口类似于“定义”操作的工作方式(请参见下面的屏幕截图)。

弹出窗口时出现

但是,我无法让弹出框在 UIWebView 中正确定位。这是我的代码的摘录,当用户选择自定义操作时会生成弹出框:

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    popover = [[UIPopoverController alloc]
                         initWithContentViewController:contentController];
    [popover setDelegate:self];
    popover.popoverContentSize = CGSizeMake(240., 60.);
    UIMenuController *menuController = [UIMenuController sharedMenuController];

    [popover presentPopoverFromRect:menuController.menuFrame
                             inView:webView
           permittedArrowDirections:UIPopoverArrowDirectionAny
                           animated:YES];
}

这是设备处于纵向模式时的结果:

弹出框的结果位置

如您所见,这还不错,但我无法使其与所选文本完全对齐;在横向模式下,弹出框的位置甚至不接近。

有谁知道我如何将弹出框正确定位到所选文本,并在用户旋转设备时正确定位?SDK 版本为 iOS 6.1。

4

2 回答 2

2

Your code is going wrong here:

[popover presentPopoverFromRect:menuController.menuFrame
                         inView:webView
       permittedArrowDirections:UIPopoverArrowDirectionAny
                       animated:YES];

You are using the menuController's view as the rect to which to anchor the popover window, whereas what you really want is the rect of the text selection.

You can get the text selection rect like so:

- (CGRect) textSelectionRect:(UITextView*)textView
{

    UITextRange *selectionRange = [textView selectedTextRange];
    NSArray *selectionRects = [self.textView selectionRectsForRange:selectionRange];
    CGRect completeRect = CGRectNull;
    for (UITextSelectionRect *selectionRect in selectionRects) {
        if (CGRectIsNull(completeRect)) {
            completeRect = selectionRect.rect;
        } else completeRect = CGRectUnion(completeRect,selectionRect.rect);
    }
    return completeRect;
}

(see answer here)

于 2013-04-11T14:12:59.287 回答
1

您可以使用 Javascript 代码从选定的文本中返回 CGRect。创建一个 file.js 并添加此代码(或将其放在 NSString 上):

// Method that gets the Rect of current selected text
// and returns in a JSON format
var getRectForSelectedText = function(elm) {
    if (typeof elm === "undefined") {
        elm = window.getSelection().getRangeAt(0);
    }

    var rect = elm.getBoundingClientRect();
    return "{{" + rect.left + "," + rect.top + "}, {" + rect.width + "," + rect.height + "}}";
}

加载 Javascript(文件或 NSString)

- (void)webViewDidFinishLoad:(UIWebView *)theWebView
{
    //Load JS file
    NSString *filePath  = [[NSBundle mainBundle] pathForResource:@"file" ofType:@"js"];
    NSData *fileData    = [NSData dataWithContentsOfFile:filePath];
    NSString *jsString  = [[NSMutableString alloc] initWithData:fileData encoding:NSUTF8StringEncoding];

    [self.webview stringByEvaluatingJavaScriptFromString:jsString];
}

现在展示你的弹出框:

CGRect rect = CGRectFromString([self.webview stringByEvaluatingJavaScriptFromString:@"getRectForSelectedText()"]);

[popover presentPopoverFromRect:rect
                         inView:webView
       permittedArrowDirections:UIPopoverArrowDirectionAny
                       animated:YES];

如果您需要在 self.view 中使用 rect,请调整框架:

- (CGRect)rectForSelectedText
{
    CGRect rect = CGRectFromString([self.webview stringByEvaluatingJavaScriptFromString:@"getRectForSelectedText()"]);
    rect.origin.x += self.webview.frame.origin.x;
    rect.origin.y += self.webview.frame.origin.y;
    return rect;
}

希望对你有所帮助!

于 2013-04-11T13:09:33.713 回答