UIWebView保存图片
2016-06-16 11:13
441 查看
现在H5混合原生开发的方式越来越流行,也就要用到UIWenview控件。在开发过程中,我们可能会遇到一个需求,要求我们保存网页上的图片,当用户点击图片的时候,就可以让用户选择是否下载图片。
在系统自带的Safari浏览器已经实现了该功能,但是iOS开发中我们如果调用UIWebView加载图片,会发现无法使用Safari保存图片的功能的。这就需要我们自己去实现。
要保存网页中的图片,关键是要获取手指点击位置的图片的url地址,这就需要从js调用oc的方法。下面介绍两种方法来实现图片保存功能,但是这两种方法都只适用于图片地址用如下形式表示才可以获取:
如果图片是通过js动态生成的,就无法使用下面的方法获取。
方法1、获取点击位置的图片的src属性
实现原理:
该方法主要是获取手指点击的位置,然后获取该位置的标签的src属性,如果是img标签,那么就可以获取到url。如果是其他标签,就无法获取到url属性。
实现代码:
分析:
上述代码的核心功能实现就是如下两行代码:
第一行代码是通过js获取点击位置的标签的src属性,第二行代码是接受向webview注入第一行的js代码后返回的src属性。
如果点击位置是图片,那么久可以通过img.src拿到图片的url地址,如果不是就返回空值。
效果展示:
打开的网页如下所示:
长按不同图片输出结果如下:
可以看到获取到了正确的图片地址
方法二、遍历Dom树获取src属性
该方法的实现比较复杂,但是灵活性更高,不仅仅适用于保存图片。而是适用于任何从js调用oc方法的场景。
1、NSObject类扩展
首先我们来给nsobject加一个类扩展,是为了可以给方法传递任意个参数,因为默认系统的performSelector方法最多只能传递两个参数
2、向webview注入js
在webview的代理方法webViewDidFinishLoad注入如下js代码
上面的方法是遍历Dom树,从中找到img标签,然后给每个img标签加上点击事件,让图片的url变
为"jscallbackoc://saveImage_*\"+this.src;形式,我们先不着急为什么这样做,先记住这里就好了,下面会给大家解释为什么这么做。
3、切割跳转url
在点击图片的时候,上面的注入的js代码就会起作用了,那么点击图片,就会触发绑定在该图片的时间,开始跳转,然后执行如下js代码
此时就会生成新的图片跳转url为:jscallbackoc://saveImage_*www.baidu.com
我们在webview的如下代理方法中,可以捕获到该url,然后切割处理
我们捕获到跳转url后,就开始做切割处理,把他转换成oc方法,先看代码
需要注意的一点就是跳转url的格式必须如下所示:
其中jscallbackoc使我们自定义的协议名字,你可以改成任意的。但是其他的部分格式必须按照上面所示
协议名格式: 协议名://
方法名: 方法签名1:方法签名2:方法签名3(方法签名用冒号连接)
参数: 参数1$参数2$参数3(多个参数用$连接)
协议名和方法名直接连接,方法名和参数用*连接
不建议把上面的冒号和$改成其他符号,比如你改成问号(?),如果原来的src的url里面包括?,那么就会出现错误。
假设被点击的图片的src地址是:www.baidu.com。那么js代码`` document.location.href=\"jscallbackoc://saveImage_\"+this.src;``生成的图片跳转url就是jscallbackoc://saveImage_www.baidu.com
经过上面的方法切割之后,得到了方法名:saveImage和参数:www.baidu.com。
然后把方法名和参数传入最后一行的该方法,就可以执行oc代码了:
此时只要在OC代码里面实现方法-(void)saveImage:(NSString *)imageURL就可以被执行了。
4、拦截跳转url
我们在webview的代理方法中,可以捕获到点击图片后的跳转url,然后做处理
在如上方法中我们做了判断,如果跳转过来的url包含了前缀"jscallbackoc://,就说明使我们自定义的方法,我们需要做拦截处理,转换为oc方法,但是其他跳转url就不做任务处理。
5、验证结果
我们分别点击网页上的不同图片,输出结果如下:
可以看到oc的方法-(void)saveImage:(NSString *)imageURL被执行了。
6、完整代码
总结:
方法1比较简洁,但是仅仅只能获取图片。
方法二比较繁琐,但是使用范围更广,不光可以保存图片,还可以执行任意的oc代码。
大家酌情选择。
在系统自带的Safari浏览器已经实现了该功能,但是iOS开发中我们如果调用UIWebView加载图片,会发现无法使用Safari保存图片的功能的。这就需要我们自己去实现。
要保存网页中的图片,关键是要获取手指点击位置的图片的url地址,这就需要从js调用oc的方法。下面介绍两种方法来实现图片保存功能,但是这两种方法都只适用于图片地址用如下形式表示才可以获取:
方法1、获取点击位置的图片的src属性
实现原理:
该方法主要是获取手指点击的位置,然后获取该位置的标签的src属性,如果是img标签,那么就可以获取到url。如果是其他标签,就无法获取到url属性。
实现代码:
上述代码的核心功能实现就是如下两行代码:
如果点击位置是图片,那么久可以通过img.src拿到图片的url地址,如果不是就返回空值。
效果展示:
打开的网页如下所示:
长按不同图片输出结果如下:
可以看到获取到了正确的图片地址
方法二、遍历Dom树获取src属性
该方法的实现比较复杂,但是灵活性更高,不仅仅适用于保存图片。而是适用于任何从js调用oc方法的场景。
1、NSObject类扩展
首先我们来给nsobject加一个类扩展,是为了可以给方法传递任意个参数,因为默认系统的performSelector方法最多只能传递两个参数
在webview的代理方法webViewDidFinishLoad注入如下js代码
上面的方法是遍历Dom树,从中找到img标签,然后给每个img标签加上点击事件,让图片的url变
为"jscallbackoc://saveImage_*\"+this.src;形式,我们先不着急为什么这样做,先记住这里就好了,下面会给大家解释为什么这么做。
3、切割跳转url
在点击图片的时候,上面的注入的js代码就会起作用了,那么点击图片,就会触发绑定在该图片的时间,开始跳转,然后执行如下js代码
我们在webview的如下代理方法中,可以捕获到该url,然后切割处理
需要注意的一点就是跳转url的格式必须如下所示:
协议名格式: 协议名://
方法名: 方法签名1:方法签名2:方法签名3(方法签名用冒号连接)
参数: 参数1$参数2$参数3(多个参数用$连接)
协议名和方法名直接连接,方法名和参数用*连接
不建议把上面的冒号和$改成其他符号,比如你改成问号(?),如果原来的src的url里面包括?,那么就会出现错误。
假设被点击的图片的src地址是:www.baidu.com。那么js代码`` document.location.href=\"jscallbackoc://saveImage_\"+this.src;``生成的图片跳转url就是jscallbackoc://saveImage_www.baidu.com
经过上面的方法切割之后,得到了方法名:saveImage和参数:www.baidu.com。
然后把方法名和参数传入最后一行的该方法,就可以执行oc代码了:
4、拦截跳转url
我们在webview的代理方法中,可以捕获到点击图片后的跳转url,然后做处理
在如上方法中我们做了判断,如果跳转过来的url包含了前缀"jscallbackoc://,就说明使我们自定义的方法,我们需要做拦截处理,转换为oc方法,但是其他跳转url就不做任务处理。
5、验证结果
我们分别点击网页上的不同图片,输出结果如下:
可以看到oc的方法-(void)saveImage:(NSString *)imageURL被执行了。
6、完整代码
总结:
方法1比较简洁,但是仅仅只能获取图片。
方法二比较繁琐,但是使用范围更广,不光可以保存图片,还可以执行任意的oc代码。
大家酌情选择。
相关文章推荐
- Export aborted because fatal lint errors were found.
- iOS的优秀开源项目
- APP微信支付的后台实现
- cocoapods 安装写使用
- iOS中我的app屏幕截图
- 高手速成android开源项目【tool篇】
- android程序如何签名和发布应用程序
- 这些小工具让你的Android 开发更高效
- 【Android之IOS风格Dialog对话框】
- <Android>学习资源推荐
- Android 递归删除文件夹下所有文件
- ios学习路线—Objective-C(NSObject)
- Android Fragment 真正的完全解析(上)
- iOS - property,strong,weak,retain,assign,copy,nomatic 的区别及使用
- Android ScrollView去掉滚动条
- Swift 解析 JSON
- iOS中蓝牙的实现方案
- android之snackbar的使用
- Android在RecyclerView/ScrollView中嵌套一个GridView或者recyclerView时只显示一行的原因及解决方法
- 浅谈Android自定义View