如何在UIWebView中获取所选文本的坐标?

8

我有一个简单的 UIWebView,其中加载了html文件。 我希望将 PopOverController 显示在所选文本上,如下图所示:

enter image description here.

我想要从 UIWebView 中获取所选文本的 coordinates。如果我将 UIWebViewscalesPageToFit 属性设置为 NO,那么此链接可以正常工作。如果我将 UIWebViewscalesPageToFit 属性设置为 YES,则会失败。

请任何人帮助我解决这个问题。


请详细说明您的问题。 - virantporwal
@virantporwal,我已经修改了我的问题以便更好地理解。 - Girish
这里的“rect”是什么意思? - virantporwal
好的,那么你可以尝试使用TapUIGestureRecognizer来获取特定坐标。 - virantporwal
@MikeM 我想从所选文本中显示弹出窗口。我已经在弹出窗口中显示了自定义项目,问题与弹出窗口的定位有关。 - Girish
显示剩余2条评论
4个回答

1

首先,像这样移除本地的长按手势识别器:

for(UIGestureRecognizer *gesRecog in yourWebView.gestureRecognizers)
    {
        if([gesRecog isKindOfClass:[UILongPressGestureRecognizer class]])
        {
            [startTF removeGestureRecognizer:gesRecog];
        }
    }

然后分配一个自定义的:
    UILongPressGestureRecognizer *myOwnLongPressRecog = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleWebViewLongpress:)];

        // set numberOfTapsRequired and numberOfTouchesRequired as per your requirement:       

[yourWebView addGestureRecognizer:myOwnLongPressRecog];

// 处理长按事件的方法:

 - (void) handleWebViewLongpress: (UIGestureRecognizer *) recog
    {
     int zoomedWidth = [[yourWebView stringByEvaluatingJavaScriptFromString:@"window.innerWidth"] intValue];

        CGFloat scale = yourWebView.frame.size.width / zoomedWidth;  // get the scaled value of your web view

        CGPoint zoomedCords = [gesture locationInView:self.webView];

        zoomedCords.x /= scale; // Normal math. Divide by the scale to get the real thing.
        zoomedCords.y /= scale;

NSLog(@"%@", zoomedCords);

            }

我已经尝试过这个,但由于scalesPageToFit属性的原因,它返回错误的y坐标。 - Girish
当缩放发生时,更改您的Y坐标。 - nr5
1
如何更改Y坐标?用户可以从UIWebView中选择任何文本。 - Girish
你必须获取缩放后的值。就像你缩放图片并想知道用户实际点击的位置一样。请查看我的更新答案。 - nr5
你之前说它没用,具体是什么问题呢?以防我遇到同样的问题... - nr5
我没有将长按手势的委托设置好,因此它没有调用其委托方法,也没有得到正确的输出。我设置了委托并且它运行良好。谢谢。 - Girish

1
这几乎完全需要在JavaScript中完成,然后将结果传回Objective C。如果您可以控制所显示的内容,可以将此函数添加到<script>标记中。否则,您需要按照this post中所述进行注入。
function rectsForSelection() {
    var i = 0, j = 0;
    var allSelections = window.getSelection();
    var result = []; // An empty array right now
    // Generally, there is only one selection, but the spec allows multiple
    for (i=0; i < allSelections.rangeCount; i++) {
        var aRange = allSelections.getRangeAt(i);
        var rects = aRange.getClientRects();
        for (j=0; j<rects.length; j++) {
            result.push(rects[j]);
        }
    }
    return JSON.stringify(result);
}

然后从您的Objective C代码中,您可以这样做:
NSString *rectsString = [webView stringByEvaluatingJavaScriptFromString:@"rectsForSelection();"];
NSData *rectsData = [rectsString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *rects = [NSJSONSerialization JSONObjectWithData:rectsData
                                                 options:0
                                                   error:NULL]; //Do Your Own Error Checking

我补充一点,这将获取在您的webView.scrollView内有效的坐标,而不是您的webView


0

你试过了吗?

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(getCoordinates:)];
//  [longPress setMinimumPressDuration:1];
[yourWebView addGestureRecognizer:longPress];


- (void)getCoordinates:(UILongPressGestureRecognizer *)sender {

CGPoint location = [sender locationInView:self.view];
NSLog(@"Tap at %1.0f, %1.0f", location.x, location.y);

}

0

UIWebView实际上将HTML渲染成UIView,具体来说,它可能会将可选择的文本渲染成UITextView,因此您需要尝试进入正确视图的委托方法。

这是一个应该有效的hack:

  1. 等待Web视图完全加载。
  2. 按照Ole Begemann 这里所述遍历UIWebView的子视图。
  3. 一旦到达UITextView,请进入其委托方法,您可以执行类似于委托链的操作以获取此 - 这里有一篇文章
  4. 实现UITextViewDelegate方法textViewDidChangeSelection:以获取所选范围并与之交互。

**步骤3和4的替代方法是使用KVO监听textView的selectedRange的更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接