如何在UIWebView中获得(X,Y)的触摸坐标

时间:2020-12-10 00:18:44

I have a UIWebView that displays a generated html table. When the user taps on a cell in the html table, my app needs to know which cell they've tapped, and the (x,y) coordinate of the tap location so I can display a popover at that point.

我有一个UIWebView显示一个生成的html表格。当用户在html表格中点击一个单元格时,我的应用程序需要知道他们已经在哪个单元格上点击了,以及点击位置的(x,y)坐标,这样我就可以在那个点显示一个弹出窗口。

I've implemented shouldStartLoadWithRequest in my UIWebView delegate. In my web page, I've embedded javascript code that captures the touch event and passes what should be the (x,y) coordinate of the touched point in a URL request as follows:

我在UIWebView委托中实现了shouldStartLoadWithRequest。在我的web页面中,我嵌入了javascript代码,它捕获了触摸事件,并传递URL请求中应该是(x,y)的触点坐标,如下所示:

var x, y;

function init()
{
    // Add an event listener for touch events - set x and y to the coordinate of the touch point
    document.addEventListener('touchstart', function(event) {
        x = event.touches[0].clientX;
        y = event.touches[0].clientY;
    }, false);
}

function cellTapped(event)
{
    window.location.href="file://myapp/dostuff?x=" + x + "&y=" + y;
}

In my html table, each cell gets an onclick event that calls cellTapped():

在我的html表中,每个单元格都得到一个onclick事件,该事件调用celltap ():

<td onclick="cellTapped(event)">...</td>

So whenever the user touches anywhere in the UIWebView, I get the coordinate of the touch point, which I save off in x and y. If they touch within one of the table cells, I receive the touch event (which sets x and y), then cellTapped() gets called and I set window.location.href, passing the (x,y) coordinate into my app.

当用户触摸的任何地方UIWebView,接触点的坐标,我保存在x和y。如果他们碰在一个桌子的细胞,我接收触摸事件(集x和y),然后cellTapped()被调用,我设置window.location。href,将(x,y)坐标传递到我的app中。

This all works beautifully. Unless the user has zoomed or scrolled the UIWebView. When they zoom or scroll, the x and y coordinates I'm getting from event.touches[0].clientX and event.touches[0].clientY are off by some varying number of pixels (varies with the amount of zoom and how far up/down or left/right the web view is scrolled).

所有这些漂亮的工作。除非用户放大或滚动了UIWebView。当它们缩放或滚动时,我从event.touch[0]中获得的x和y坐标。clientX和event.touches[0]。clientY其实是一些不同数量的像素(随着缩放的程度以及web视图上下滚动的距离而变化)。

Is there some way to determine the zoom ratio and scroll position of the web view so that I can adjust my x and y coordinates accordingly? The zoomScale and contentOffset properties from UIScrollView do not seem to be exposed in UIWebView.

是否有办法确定web视图的缩放比例和滚动位置,以便我可以相应地调整x和y坐标?UIScrollView的zoomScale和contentOffset属性似乎不在UIWebView中公开。

2 个解决方案

#1


2  

Use UIGestureRecognizerDelegate method:

使用UIGestureRecognizerDelegate方法:

Add UIGestureRecognizerDelegate in declaration file (i.e. your .h file)

在声明文件(即.h文件)中添加UIGestureRecognizerDelegate

Step 1: Just set the delegate of gestureRecognizer: (in .m file)

步骤1:只需设置gestureRecognizer:(在.m文件中)的委托

UITapGestureRecognizer *webViewTapped = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
webViewTapped.numberOfTapsRequired = 1;
webViewTapped.delegate = self;
[webView addGestureRecognizer:webViewTapped];
[webViewTapped release];

Step 2: Override this function: (in .m file)

步骤2:覆盖这个函数:(在.m文件中)

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

Step 3: Now implement the tapAction function:

步骤3:现在实现tapAction函数:

- (void)tapAction:(UITapGestureRecognizer *)sender
{    
    CGPoint point = [sender locationInView:self.view]; // get x and y from here
}

#2


1  

EDIT: In iOS 5 and above, the scrollView property of UIWebView is exposed and accessible so this becomes a non-issue. In my case, I still need to support devices running iOS 4 (believe it or not...), so the following solves it for older versions.

编辑:在ios5和以上版本中,UIWebView的scrollView属性是公开的,可以访问的,所以这不是问题。在我的例子中,我仍然需要支持运行ios4的设备(信不信由你…),所以下面的例子解决了旧版本的问题。

By looping through the subviews of my UIWebView, I can find the underlying UIScrollView, then use its zoomScale and contentOffset properties to find the zoom and scroll position:

通过循环浏览我的UIWebView的子视图,我可以找到底层的UIScrollView,然后使用它的缩放比例和contentOffset属性来找到缩放和滚动位置:

for (UIView *view in myWebView.subviews) 
{
    if ([view isKindOfClass:[UIScrollView class]]) 
    {
        // Get UIScrollView object
        scrollview = (UIScrollView *) view;

        // Find the zoom and scroll offsets
        float zoom = scrollView.zoomScale;
        float xOffset = scrollView.contentOffset.x;
        float yOffset = scrollView.contentOffset.y;
    }
}

I don't know if Apple would approve of this for app store submission, since I assume they had their reasons for not exposing the underlying UIScrollView object, but it does solve my problem. My app is distributed under an Enterprise license anyway, so app store submission isn't an issue for me.

我不知道苹果是否会批准这个应用商店提交,因为我认为他们有他们不公开底层UIScrollView对象的理由,但它确实解决了我的问题。我的应用是在企业许可证下发布的,所以应用商店提交对我来说不是问题。

#1


2  

Use UIGestureRecognizerDelegate method:

使用UIGestureRecognizerDelegate方法:

Add UIGestureRecognizerDelegate in declaration file (i.e. your .h file)

在声明文件(即.h文件)中添加UIGestureRecognizerDelegate

Step 1: Just set the delegate of gestureRecognizer: (in .m file)

步骤1:只需设置gestureRecognizer:(在.m文件中)的委托

UITapGestureRecognizer *webViewTapped = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
webViewTapped.numberOfTapsRequired = 1;
webViewTapped.delegate = self;
[webView addGestureRecognizer:webViewTapped];
[webViewTapped release];

Step 2: Override this function: (in .m file)

步骤2:覆盖这个函数:(在.m文件中)

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

Step 3: Now implement the tapAction function:

步骤3:现在实现tapAction函数:

- (void)tapAction:(UITapGestureRecognizer *)sender
{    
    CGPoint point = [sender locationInView:self.view]; // get x and y from here
}

#2


1  

EDIT: In iOS 5 and above, the scrollView property of UIWebView is exposed and accessible so this becomes a non-issue. In my case, I still need to support devices running iOS 4 (believe it or not...), so the following solves it for older versions.

编辑:在ios5和以上版本中,UIWebView的scrollView属性是公开的,可以访问的,所以这不是问题。在我的例子中,我仍然需要支持运行ios4的设备(信不信由你…),所以下面的例子解决了旧版本的问题。

By looping through the subviews of my UIWebView, I can find the underlying UIScrollView, then use its zoomScale and contentOffset properties to find the zoom and scroll position:

通过循环浏览我的UIWebView的子视图,我可以找到底层的UIScrollView,然后使用它的缩放比例和contentOffset属性来找到缩放和滚动位置:

for (UIView *view in myWebView.subviews) 
{
    if ([view isKindOfClass:[UIScrollView class]]) 
    {
        // Get UIScrollView object
        scrollview = (UIScrollView *) view;

        // Find the zoom and scroll offsets
        float zoom = scrollView.zoomScale;
        float xOffset = scrollView.contentOffset.x;
        float yOffset = scrollView.contentOffset.y;
    }
}

I don't know if Apple would approve of this for app store submission, since I assume they had their reasons for not exposing the underlying UIScrollView object, but it does solve my problem. My app is distributed under an Enterprise license anyway, so app store submission isn't an issue for me.

我不知道苹果是否会批准这个应用商店提交,因为我认为他们有他们不公开底层UIScrollView对象的理由,但它确实解决了我的问题。我的应用是在企业许可证下发布的,所以应用商店提交对我来说不是问题。