Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get (X,Y) coordinate of touch in UIWebView

Tags:

ios

uiwebview

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.

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:

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():

<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.

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).

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.

like image 338
Jeff Loughlin Avatar asked Aug 13 '13 13:08

Jeff Loughlin


2 Answers

Use UIGestureRecognizerDelegate method:

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

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

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)

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

Step 3: Now implement the tapAction function:

- (void)tapAction:(UITapGestureRecognizer *)sender
{    
    CGPoint point = [sender locationInView:self.view]; // get x and y from here
}
like image 56
Samkit Jain Avatar answered Oct 21 '22 01:10

Samkit Jain


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.

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:

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.

like image 31
Jeff Loughlin Avatar answered Oct 21 '22 01:10

Jeff Loughlin