美文网首页iOS程序犭袁iOS精英班iOS奋斗
UIWebView+AppFrame 获取被点击图片的地址

UIWebView+AppFrame 获取被点击图片的地址

作者: 一滴水的世界 | 来源:发表于2017-01-19 14:51 被阅读1575次

    加载网页时,有时候产品经理会提出一个需求:点击界面的图片,可以进行查看大图操作。可是,我之前一直觉得这是需要和前端同事合作才能完成。最近自己利用网上公布的知乎日报API,自己模拟现在的知乎日报APP去写了首页和详情页面。ZhiHURiBaodemo地址
    其中详情页面需要支持点击图片查看大图功能,这个实现困扰了我一段时间,我想了很多种方案,自己一个人折腾了好几天,现在目前最好的方案出来了,那就是 UIWebView+AppFrame 使用的demo地址.


    其中实现的原理是:给 UIWebView 添加 tap手势 ,利用手势的代理方法

    -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch

    可以获取到手指点击触点在界面的位置,再使用 JS 可以获取到该点显示的元素,这样就可以获取到 img 标签,拿到图片的地址。但是,这个方法是只要有手势就会响应,也就是说,只要你的手指在界面上面移动就会触发,如果说,这个时候你就将拿到的图片地址用来显示,就会出现在滑动的过程中展示大图,这个效果肯定是不符合交互过程的。那么使用这个方法我们能够做什么呢?明显的是,我们可以拿到图片的链接,但是这个方法调用的频率很高,这里需要过滤

    -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
        if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
            if (gestureRecognizer == self.af_customTap) {
                CGPoint touchPoint = [touch locationInView:self];
                NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", touchPoint.x, touchPoint.y];
                NSString *URLString = [self stringByEvaluatingJavaScriptFromString:imgURL];
                self.af_isClickImage = @(NO);
                if (URLString && URLString.length > 0) {
                    self.af_isClickImage = @(YES);
                    self.af_imageString = URLString;
                }
            }
        }
        return YES;
    }
    

    这个过滤可以做到拿到最近的图片的地址,简单来说就是拿到我们想要显示的图片的地址,那么现在的问题就是显示图片的时机。这个方法的任务已经完成了,所以我就再次去 UIGestureRecognizerDelegate 找有有关的代理方法,发现只有在这个

    -(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;

    方法中做文章了,没错就是在这个方法中实现回调。具体的代码也十分简单,注意这里我们返回的是 NO 因为我们使用这个手势,实质上面是获取手指在界面上面滑动获取位置,并不是需要添加手势事件。

    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
        if (gestureRecognizer == self.af_customTap) {
            if (self.af_imageString && [self.af_isClickImage boolValue]) {
                !self.af_clickImage ? : self.af_clickImage(self.af_imageString);
                self.af_imageString = nil;
            }
            return NO; /// 这里返回 NO 不需要响应手势
        }
    
        return YES;
    }
    

    现在我们看看头文件的内容:

    /// 点击图片回调 返回被点击图片的地址字符串

    -(void)af_didClickImageCall:(void(^)(NSString* URLString)) clickImage;

    就是需要的获取 webView 中的图片时,使用这个方法,回调的 Block 会将对应的图片地址给你。这个回调方法中写展示大图的逻辑;整个比较详细的使用可以看我的项目.

    存在的不足:实现上面是添加了一个 tap手势(这个手势不会影响 webView 原有手势的响应),但是,对于 web 页面的所有图片都会有回调,可能在某些使用场景下需要过滤一些图片,例如头像之类的小图片。这个还需要使用者自己修改相关的 JS 代码,过滤网页的某些图片标签。或者,拿到图片地址之后做相应的过滤操作。

    参考博客:地址

    相关文章

      网友评论

      • unhangcorn:大兄弟,你确定demo能用吗?我点了图片没放大,就输出了图片的地址
        unhangcorn:@一滴水的世界 大兄弟 谦虚了,收下这双膝盖吧
        一滴水的世界:@unhangcorn demo 只是打印了图片地址。。。我写的另外一个demo有看大图效果,不过写的不好 (传上地址:https://github.com/hqyangtze/ZhiHuRiBaoDemo)
      • 259ef7ae0bd1:遍历body里的img标签,都绑定上onclick事件,这样更简单吧
        259ef7ae0bd1:webview加载完执行这个js
        259ef7ae0bd1:@一滴水的世界

        var imgs = document.getElementsByTagName('img');
        for (var i = 0; i < imgs.length; i++) {
        var img = imgs[i];
        img.onclick = (function (img) {
        return function () {
        //把img.src传给oc
        };
        })(img);
        }
        一滴水的世界:@Simony 恩恩,那实现的代码呢:innocent:
      • 九零后_:当然自己做这是比较好的处理方法,但是图片过滤这个问题很难解决,我们实现还是和前端同事合作下。才比较完美
        一滴水的世界:在实际的项目中,结合需求和前端协商的方案肯定比这个好。:smile:
      • e8a008284a9e:最近也做了这个功能,但是拿到图片URL后使用sdwebimage下载展示,但是遇到图片很大的时候会导致内存过大crash 如何解决呢
        一滴水的世界:我说的是,关于你们项目的,如果是外部链接,肯定没有办法的。
        e8a008284a9e:这是网页里的图片后台给不太可能,用户可以加载任何网页,后台不可能把图片抓取压缩再给个小图
        一滴水的世界:@e8a008284a9e 你说图片过大,这个根据你的需求来吧,一般让后台给占用空间小的图片。如果图片不多的话,一般场景下不会发生奔溃的,可能是代码中有些地方没有处理好。:smile:
      • 横穿撒哈拉的骆驼:楼主这个方法很好, 不用和FE配合了, 我看我们的程序时FE在web上加了一个方法, 在点击的时候调用本地的方法, 将图片的的url传给客户端显示
        一滴水的世界:@海棠花开 是啊,就是为了方便,我也尝试了许久。

      本文标题:UIWebView+AppFrame 获取被点击图片的地址

      本文链接:https://www.haomeiwen.com/subject/yeeibttx.html