打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

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

思路: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];

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


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

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


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

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

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

本文遵循“署名-非商业用途-保持一致”创作公用协议


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
UIWebView滚动到底部的代码
JS与iOS之间的通信
【获取、高亮UIWebView中选择的文本】How To Mark Or Get The Highlighted String Inside UIWebView
Objective-C与JavaScript的交互
IOS应用通过UIWEBVIEW实现与JS交互
iOS开发 webView的学习及js交互
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服