自定义 UIWebview 添加长按保存图片等操作

http://blog.csdn.net/mangosnow/article/details/38933613


思路:safari 自带了长按保存的功能,分析这个功能的特点: 长按一个图片,保存后的图片就是所点击的图片,做到了精确定位。JS可以处理精确定位的问题,使用UIWebview 和 JS 能够解决我们的问题。

直接上代码


[objc]  view plain  copy
 print ?
  1. UIWebView *aWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0.00, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];  
  2.     aWebView.delegate = self;  
  3.     aWebView.scalesPageToFit = YES;  
  4.      
  5.     self.mainWebView = aWebView;  
  6.     [self.view addSubview:aWebView];  
  7.     NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://image.baidu.com/"] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:20];  
  8.     [self.mainWebView loadRequest:request];  
  9.      
  10.     UILongPressGestureRecognizer *longtapGesture = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longtap:)];  
  11.     [self.view addGestureRecognizer:longtapGesture];  

添加webview,添加长按手势,看起来没有什么。


[objc]  view plain  copy
 print ?
  1. -(void)longtap:(UILongPressGestureRecognizer * )longtapGes{  
  2.      
  3.     if (longtapGes.state == UIGestureRecognizerStateBegan) {  
  4.         CGPoint pt = [longtapGes locationInView:self.view];  
  5.         pt= [self.mainWebView convertPoint:pt fromView:nil];  
  6.          
  7.         CGPoint offset  = [self.mainWebView.scrollView contentOffset];  
  8.         CGSize viewSize = [self.view frame].size;  
  9.         CGSize windowSize = [self.view frame].size;  
  10.          
  11.         CGFloat f = windowSize.width / viewSize.width;  
  12.         pt.x = pt.x * f + offset.x;  
  13.         pt.y = pt.y * f + offset.y;  
  14.          
  15.         [self openContextualMenuAt:pt];  
  16.     }  
  17. }  

注意看下这段代码 
pt 为映射在webview 上的坐标
得到坐标后,根据contentOffset,获取到点击的坐标上在 web 绝对位置上的坐标点。


[objc]  view plain  copy
 print ?
  1. - (void)openContextualMenuAt:(CGPoint)pt  
  2. {  
  3.     NSString *path = [[NSBundle mainBundle] pathForResource:@"test1" ofType:@"txt"];  
  4.      
  5.     NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];  
  6.     [self.mainWebView stringByEvaluatingJavaScriptFromString: jsCode];  
  7.      
  8.     NSString *tags = [self.mainWebView stringByEvaluatingJavaScriptFromString:  
  9.                       [NSString stringWithFormat:@"MyAppGetHTMLElementsAtPoint(%i,%i);",(NSInteger)pt.x,(NSInteger)pt.y]];  
  10.      
  11.     UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Contextual Menu"  
  12.                                                        delegate:self cancelButtonTitle:@"Cancel"  
  13.                                          destructiveButtonTitle:nil otherButtonTitles:nil];  
  14.      
  15.     if ([tags rangeOfString:@",A,"].location != NSNotFound) {  
  16.         [sheet addButtonWithTitle:@"打开链接"];  
  17.     }  
  18.      
  19.     if ([tags rangeOfString:@",IMG,"].location != NSNotFound) {  
  20.         NSString *str = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", pt.x, pt.y];  
  21.         NSString *imgStr= [self.mainWebView stringByEvaluatingJavaScriptFromString: str];  
  22.         NSLog(@"启动一个request下载图片:%@",imgStr);  
  23.         [sheet addButtonWithTitle:@"保存图片"];  
  24.     }  
  25.      
  26.      
  27.     [sheet addButtonWithTitle:@"在Safari中打开"];  
  28.      
  29.     [sheet showInView:self.view];  
  30. }  
test1.txt 内容如下

[javascript]  view plain  copy
 print ?
  1. function MyAppGetHTMLElementsAtPoint(x,y) {  
  2.     var tags = ",";  
  3.     var e = document.elementFromPoint(x,y);  
  4.     while (e) {  
  5.         if (e.tagName) {  
  6.             tags += e.tagName + ',';  
  7.         }  
  8.         e = e.parentNode;  
  9.     }  
  10.     return tags;  
  11. }  

这段js 能够返回 web 内容坐标对应 web 节点
然后通过注入方式调用js,并获取到图片地址

[objc]  view plain  copy
 print ?
  1. NSString *str = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", pt.x, pt.y];  
  2. NSString *imgStr= [self.mainWebView stringByEvaluatingJavaScriptFromString: str];  

到这里,我们的任务已经完成了大半了。
还需要做的是弹出选择框,用户选择操作,代码实现选择操作。此处省略若干代码和说明。


[objc]  view plain  copy
 print ?
  1. -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex  
  2. {  
  3.     // 这里实际启动request,下载图片  
  4.     // 我看见UC 浏览器断网也是可以下载图片的,我大概知道是通过JS,但具体操作就不知道了,有没有人知道是怎么实现的,分享下  
  5. }  
  6.   
  7. -(void)webViewDidFinishLoad:(UIWebView *)webView  
  8. {  
  9.     [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];  
  10.     [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];  
  11.      
  12. }  

这里 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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值