During development of iPad media application, we have found a good way to save an image from a webpage on iPad.
In this article we’d like to talk about saving image from an UIWebView on iPad.
First of all we need to think about what event should initialize saving of an image from a UIWebView? The most beautiful solution is imitate Safari behavior: add UILongPressGestureRecognizer to UIWebView and process long tap. Unfortunately, this gesture is not recognized in UIWebView, and some other gestures too.
There is a well-working method – two fingers taps. Here is a code example which adds recognizer to UIWebView:
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)]; doubleTap.numberOfTouchesRequired = 2; [self.wvBrowser addGestureRecognizer:doubleTap];
Two fingers tap handler looks like this:
-(void) doubleTap :(UITapGestureRecognizer*) sender
{
<Find HTML tag which was clicked by user>
<If tag is IMG, then get image URL and start saving>
}
HTML tag is found by JavaScript code:
document.elementFromPoint(x, y)
This JavaScript code can be executed by stringByEvaluatingJavaScriptFromString method from UIWebView class. There is a complication in calculating x and y coordinates. You need to take into account that content of WebView can be scaled or scrolled.
Offset is calculated like this:
int scrollPositionY = [[self.wvBrowser stringByEvaluatingJavaScriptFromString:@"window.pageYOffset"] intValue]; int scrollPositionX = [[self.wvBrowser stringByEvaluatingJavaScriptFromString:@"window.pageXOffset"] intValue];
Scale ratio is relation of browser window width (window.outerWidth) to width of UIWebView:
int displayWidth = [[self.wvBrowser stringByEvaluatingJavaScriptFromString:@"window.outerWidth"] intValue]; CGFloat scale = wvBrowser.frame.size.width / displayWidth;
Coordinates of tap in HTML document are calculated like this:
CGPoint pt = [sender locationInView:self.wvBrowser]; pt.x *= scale; pt.y *= scale; pt.x += scrollPositionX; pt.y += scrollPositionY;
When you get tap coordinates, first you should check tag name clicked by user:
NSString *js = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).tagName", pt.x, pt.y]; NSString * tagName = [self.wvBrowser stringByEvaluatingJavaScriptFromString:js];
If IMG tag was tapped, then you just need to get image URL:
NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", startPoint.x, startPoint.y]; NSString *urlToSave = [self.wvBrowser stringByEvaluatingJavaScriptFromString:imgURL];
And that’s it! Now you can save any image from a WebView on your iPad.



This is great for getting the URL of an image that is tapped and held. Is there a similar way (minor change to the javascript executed?) to get the URL of a link that is tapped and held? Or the URL of a link attached to an image (not the image itself, but the target link?)
Thanks
hi…
i could not understand ,how this code would be reside
can u please give me proper code by which i can use it easily
thanks
YOU ROCK! THANK YOU SOOOOOOOO SO SO MUCH!
It doesn’t work. The gesture didn’t get recognized. I tested it on iOS 5.1 & 6.0. I set exclusiveTouch as well as implementing gesture delegate, etc.
It dose work, at least for me on ios 6.0, it’s quite a nice gesture
Hello,
Thank you for the tutorial. This looks like what I need. My question is what file is this code inserted into?
Thank you