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

6
我有一个UIWebView来显示生成的HTML表格。当用户点击HTML表格中的单元格时,我的应用程序需要知道他们点击了哪个单元格,并且需要知道点击位置的(x,y)坐标,以便在该点显示一个气泡窗口。
我已经在UIWebView代理中实现了shouldStartLoadWithRequest函数。在我的网页中,我嵌入了捕获触摸事件的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;
}

在我的html表格中,每个单元格都会得到一个onclick事件,调用cellTapped()函数:
<td onclick="cellTapped(event)">...</td>

每当用户在UIWebView中点击任何地方时,我都会得到触摸点的坐标,并将其保存在x和y中。如果他们在表格单元格中触摸,则我接收到触摸事件(设置x和y),然后调用cellTapped()并设置window.location.href,将(x,y)坐标传递给我的应用程序。

这一切都非常漂亮。除非用户已经缩放或滚动了UIWebView。当他们缩放或滚动时,我从event.touches[0].clientX和event.touches[0].clientY获取的x和y坐标会偏离一些变化的像素数(与缩放量和Web视图向上/向下或向左/向右滚动的距离有关)。

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


2个回答

2

使用UIGestureRecognizerDelegate方法:

在声明文件中添加UIGestureRecognizerDelegate(例如您的.h文件)

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

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

步骤2:覆盖此函数(在.m文件中):
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

步骤三:现在实现tapAction函数:
- (void)tapAction:(UITapGestureRecognizer *)sender
{    
    CGPoint point = [sender locationInView:self.view]; // get x and y from here
}

我认为你无法在UIWebView上实现这个功能,因为Web视图会在手势识别器看到它之前拦截点击。 - Jeff Loughlin
尝试过了。tapAction从未被调用,因为UIWebView拦截了该点击事件并且没有传递它。 - Jeff Loughlin

1
编辑: 在iOS 5及以上版本中,UIWebView的scrollView属性已经公开和可访问,因此这不再是一个问题。在我的情况下,我仍然需要支持运行iOS 4的设备(信不信由你...),所以下面的解决方案适用于旧版本。

通过循环遍历UIWebView的子视图,可以找到底层的UIScrollView,然后使用它的zoomScalecontentOffset属性来查找缩放和滚动位置:

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;
    }
}

我不知道苹果是否会批准这种将底层UIScrollView对象暴露出来的应用程序提交至应用商店,因为我认为他们有自己的原因。但是这确实解决了我的问题。无论如何,我的应用程序已经在企业许可下分发,所以应用商店的提交对我来说不是问题。

-[UIWebView scrollView] 属性不是你想要的吗?https://developer.apple.com/library/ios/documentation/uikit/reference/UIWebView_Class/Reference/Reference.html#//apple_ref/occ/instp/UIWebView/scrollView - axiixc
@axiixc: 我仍需要支持运行iOS 4的设备(是的,我知道...),而scrollView属性仅在iOS 5及以上版本上可用。我已经进行了编辑以澄清这一点。 - Jeff Loughlin

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