思路:safari 自带了长按保存的功能,分析这个功能的特点: 长按一个图片,保存后的图片就是所点击的图片,做到了精确定位。JS可以处理精确定位的问题,使用UIWebview 和 JS 能够解决我们的问题。
直接上代码
UIWebView *aWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0.0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
aWebView.delegate = self;
aWebView.scalesPageToFit = YES;
self.mainWebView = aWebView;
[self.view addSubview:aWebView];
NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://image.baidu.com/"] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:20];
[self.mainWebView loadRequest:request];
UILongPressGestureRecognizer *longtapGesture = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longtap:)];
[self.view addGestureRecognizer:longtapGesture];
-(void)longtap:(UILongPressGestureRecognizer * )longtapGes{
if (longtapGes.state == UIGestureRecognizerStateBegan) {
CGPoint pt = [longtapGes locationInView:self.view];
pt= [self.mainWebView convertPoint:pt fromView:nil];
CGPoint offset = [self.mainWebView.scrollView contentOffset];
CGSize viewSize = [self.view frame].size;
CGSize windowSize = [self.view frame].size;
CGFloat f = windowSize.width / viewSize.width;
pt.x = pt.x * f + offset.x;
pt.y = pt.y * f + offset.y;
[self openContextualMenuAt:pt];
}
}
- (void)openContextualMenuAt:(CGPoint)pt
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"test1" ofType:@"txt"];
NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[self.mainWebView stringByEvaluatingJavaScriptFromString: jsCode];
NSString *tags = [self.mainWebView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"MyAppGetHTMLElementsAtPoint(%i,%i);",(NSInteger)pt.x,(NSInteger)pt.y]];
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Contextual Menu"
delegate:self cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil otherButtonTitles:nil];
if ([tags rangeOfString:@",A,"].location != NSNotFound) {
[sheet addButtonWithTitle:@"打开链接"];
}
if ([tags rangeOfString:@",IMG,"].location != NSNotFound) {
NSString *str = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", pt.x, pt.y];
NSString *imgStr= [self.mainWebView stringByEvaluatingJavaScriptFromString: str];
NSLog(@"启动一个request下载图片:%@",imgStr);
[sheet addButtonWithTitle:@"保存图片"];
}
[sheet addButtonWithTitle:@"在Safari中打开"];
[sheet showInView:self.view];
}
test1.txt 内容如下
function MyAppGetHTMLElementsAtPoint(x,y) {
var tags = ",";
var e = document.elementFromPoint(x,y);
while (e) {
if (e.tagName) {
tags += e.tagName + ',';
}
e = e.parentNode;
}
return tags;
}
NSString *str = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", pt.x, pt.y];
NSString *imgStr= [self.mainWebView stringByEvaluatingJavaScriptFromString: str];
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
// 这里实际启动request,下载图片
// 我看见UC 浏览器断网也是可以下载图片的,我大概知道是通过JS,但具体操作就不知道了,有没有人知道是怎么实现的,分享下
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
}
这里 webview 一旦加载完成了,通过JS注入,这段js 直接去除了点击和选中效果,否则会出现uiwebview 自带copy 工具,以及选中变灰的效果。
总结:
在webview 加载完成之后,禁用掉webview自带的选择和长按事件。
在外部添加长按事件,并映射成webview中长按事件所处的位置px
在通过调用stringByEvaluatingJavaScriptFromString:@""方法获取到上步中px所处位置的 html 节点
同样通过调用stringByEvaluatingJavaScriptFromString:@""方法得到节点的 src 信息
新开请求去获得图片
我看见UC 浏览器断网也是可以下载图片的,我大概知道是通过JS,但具体操作就不知道了,有没有人知道是怎么实现的,分享下
DEMO下载地址:https://github.com/chexsong/WorkingDemos
车小松(http://blog.csdn.net/mangosnow)
本文遵循“署名-非商业用途-保持一致”创作公用协议