美文网首页iOS开发专题键盘上的鼓手IOS 超级无敌
iOS中加载HTML数据,并点击图片或链接进行相应的操作

iOS中加载HTML数据,并点击图片或链接进行相应的操作

作者: 若锦 | 来源:发表于2016-07-04 13:09 被阅读7219次

    开发中,有时候我们需要展现HTML类型的数据,这时候,我们多数选择用UIWebView加载,但是当我们需要加载大量的HTML数据时,使用UIWebView加载,性能会降低,尤其是当UITableViewCell需要放大量的HTML数据时,如果你用UIWebView加载这些HTML数据,你会发现,tableview会有卡顿的现象。

    那怎样去优化这个卡顿现象呢?我们知道WKWbebView的加载速度比UIWebView提升差不多一倍的, 内存使用上面,反而还少了一半,所以我们可以采用WKWebView对其进行优化。今天把一个三方类介绍给大家,那就是IMYWebView,这个类兼容WKWebView和UIWebView,实现了UIWebView到WKWebView的对接,即使你之前的项目是用的UIWebView,那也没关系,只要将UIWebView换成IMYWebView就可以了。

    另外,加载HTML数据自然绝多数会有图片和内置链接,我们也会希望可以点击图片进行浏览、放大和缩小,可以点开链接,那么,该怎样去实现呢?

    1、在工程中导入IMYWebView

    #import "IMYWebView.h"
    

    2、创建IMYWebView,并嵌套到TableView中,实现tableview的相关代理方法

    @interface ViewController ()<UITableViewDataSource, UITableViewDelegate,IMYWebViewDelegate,HZPhotoBrowserDelegate>
    @property(nonatomic, strong)UITableView *tableView;
    @property(nonatomic, assign)CGFloat webviewHight;//记录webview的高度
    @property(nonatomic, copy)NSString *HTMLData;//需要加载的HTML数据
    @property(nonatomic, strong)NSMutableArray *imageArray;//HTML中的图片个数
    @property(nonatomic, strong)IMYWebView *IMYwebView;
     
    @end
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.navigationController.navigationBar.translucent = NO;
        self.title = @"tableviewcell嵌套webview载HTML";
        self.view.backgroundColor = [UIColor whiteColor];
    //    获取HTML数据
         [self getHTMLData];
        
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width , self.view.frame.size.height - 64) style:UITableViewStylePlain];
        _tableView.dataSource = self;
        _tableView.delegate = self;
        
        _tableView.tableHeaderView = [[UIView alloc] init];
        [self.view addSubview:_tableView];
        _htmlWebView = [[IMYWebView alloc] init];
        _htmlWebView.frame = CGRectMake(0, 0, _tableView.frame.size.width, 1);
        _htmlWebView.delegate = self;
        _htmlWebView.scrollView.scrollEnabled = NO;//设置webview不可滚动,让tableview本身滚动即可
        _htmlWebView.scrollView.bounces = NO;
        _htmlWebView.opaque = NO;
        
    }
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return 4;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        if (indexPath.row != 3) {
             return 60;
        }else{
            
            return _webviewHight;//cell自适应webview的高度
        }
       
    }
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        static NSString *identifier = @"cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    
        if (!cell) {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
                
                    }
        if (indexPath.row == 3) {
            
            [cell.contentView addSubview:_htmlWebView];
    
            //加载HTML数据
            [_htmlWebView loadHTMLString:_HTMLData baseURL:nil];
            
        }else{
            
            cell.textLabel.text = [NSString stringWithFormat:@"第%ld行",(long)indexPath.row];
          
        }
         return cell;
    }
    

    3、实现IMYWebView的相关代理方法

    -(void)webViewDidFinishLoad:(IMYWebView *)webView{
    //加载完毕后重新计算webview的高度
        [self.htmlWebView evaluateJavaScript:@"document.documentElement.scrollHeight" completionHandler:^(id object, NSError *error) {
            CGFloat height = [object integerValue];
            
            if (error != nil) {
                
            }else{
                _webviewHight = height;
                [_tableView beginUpdates];
                self.htmlWebView.frame = CGRectMake(_htmlWebView.frame.origin.x,_htmlWebView.frame.origin.y, _tableView.frame.size.width, _webviewHight );
                  [_tableView endUpdates];
            }
      
        }];
        
    //    插入js代码,对图片进行点击操作
        [webView evaluateJavaScript:@"function assignImageClickAction(){var imgs=document.getElementsByTagName('img');var length=imgs.length;for(var i=0; i < length;i++){img=imgs[i];if(\\"ad\\" ==img.getAttribute(\\"flag\\")){var parent = this.parentNode;if(parent.nodeName.toLowerCase() != \\"a\\")return;}img.onclick=function(){window.location.href='image-preview:'+this.src}}}" completionHandler:^(id object, NSError *error) {
            
        }];
        [webView evaluateJavaScript:@"assignImageClickAction();" completionHandler:^(id object, NSError *error) {
            
        }];
    
        //获取HTML中的图片
        [self getImgs];
     
    
    }
    
    -(BOOL)webView:(IMYWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
        
        if ([request.URL isEqual:@"about:blank"])
        {
            return true;
        }
        if ([request.URL.scheme isEqualToString: @"image-preview"])
        {
            
            NSString *url = [request.URL.absoluteString substringFromIndex:14];
            
            
            //启动图片浏览器, 跳转到图片浏览页面
            if (_imageArray.count != 0) {
                
                HZPhotoBrowser *browserVc = [[HZPhotoBrowser alloc] init];
                browserVc.imageCount = self.imageArray.count; // 图片总数
                browserVc.currentImageIndex = [_imageArray indexOfObject:url];//当前点击的图片
                browserVc.delegate = self;
                [browserVc show];
                
            }
            return NO;
            
        }
        
        //    用户点击文章详情中的链接
        if ( navigationType == UIWebViewNavigationTypeLinkClicked ) {
            
                WebViewURLViewController *webViewVC = [WebViewURLViewController new];
                webViewVC.URLString = request.URL.absoluteString;
                [self.navigationController pushViewController:webViewVC animated:YES];
            
            
            return NO;
        }
            
            return YES;
    }
    
    

    4、获取文章图片个数的方法

    #pragma mark -- 获取文章中的图片个数
    - (NSArray *)getImgs
    {
       
        NSMutableArray *arrImgURL = [[NSMutableArray alloc] init];
        for (int i = 0; i < [self nodeCountOfTag:@"img"]; i++) {
            NSString *jsString = [NSString stringWithFormat:@"document.getElementsByTagName('img')[%d].src", i];
            [_htmlWebView evaluateJavaScript:jsString completionHandler:^(NSString *str, NSError *error) {
                
                if (error ==nil) {
                    [arrImgURL addObject:str];
                }
           
            }];
        }
        _imageArray = [NSMutableArray arrayWithArray:arrImgURL];
        
        
        return arrImgURL;
    }
    
    // 获取某个标签的结点个数
    - (NSInteger)nodeCountOfTag:(NSString *)tag
    {
        
        NSString *jsString = [NSString stringWithFormat:@"document.getElementsByTagName('%@').length", tag];
     
       int count =  [[_htmlWebView stringByEvaluatingJavaScriptFromString:jsString] intValue];
        
        return count;
    }
    
    

    5、点击图片进行浏览的相关方法,这个图片浏览是封装好的一个浏览器,在这里暂时不做介绍

    #pragma mark - photobrowser代理方法
    - (UIImage *)photoBrowser:(HZPhotoBrowser *)browser placeholderImageForIndex:(NSInteger)index
    {
        //图片浏览时,未加载出图片的占位图
        return [UIImage imageNamed:@"gg_pic@2x"];
        
    }
    
    - (NSURL *)photoBrowser:(HZPhotoBrowser *)browser highQualityImageURLForIndex:(NSInteger)index
    {
        NSString *urlStr = [self.imageArray[index] stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"bmiddle"];
       
    

    6、最后的运行结果如图:


    结果示意图

    7.有时候我们需要给webview加个头视图或者尾视图,跟随webview一起滚动,如果这时我们的webview不是嵌在tableview中的,那该怎么办呢?很简单,只要将头视图加在webview的scrollview上,设置scrollview的contentInset(UIEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right)头视图的高度为top,尾视图的高度为bottom,根据自己的需要去设置相应的高度)就可以了

        //给scrollview添加头视图
        //设置web view的scrollView的上、左、下、右的距离
        _wkwebView.scrollView.contentInset = UIEdgeInsetsMake(40, 0, 0, 0);
        _titleLabel = [[UILabel alloc] init];
        [_wkwebView.scrollView addSubview:_titleLabel];
        _titleLabel.frame = CGRectMake(0, -40, self.wkwebView.frame.size.width, 40);
        [self.wkwebView.scrollView addSubview:_titleLabel];
      _titleLabel.text = @"web view的头视图";
    

    8、最后,给大家分享一些用js获取网页一些相关元素的代码

    document:属性
    
    document.title                 //设置文档标题等价于HTML的<title>标签
    document.bgColor               //设置页面背景色
    document.fgColor               //设置前景色(文本颜色)
    document.linkColor             //未点击过的链接颜色
    document.alinkColor            //激活链接(焦点在此链接上)的颜色
    document.vlinkColor            //已点击过的链接颜色
    document.URL                   //设置URL属性从而在同一窗口打开另一网页
    document.fileCreatedDate       //文件建立日期,只读属性
    document.fileModifiedDate      //文件修改日期,只读属性
    document.fileSize              //文件大小,只读属性
    document.cookie                //设置和读出cookie
    document.charset               //设置字符集 简体中文:gb2312
    
    
    document:方法
    document.write()                      //动态向页面写入内容
    document_createElement_x_x(Tag)           //创建一个html标签对象
    document.getElementByIdx_x_x(ID)           //获得指定ID值的对象
    document.getElementsByName(Name)      //获得指定Name值的对象
    document.body.a(oTag)
    
    
    body:子对象
    
    document.body                   //指定文档主体的开始和结束等价于<body></body>
    document.body.bgColor           //设置或获取对象后面的背景颜色
    document.body.link              //未点击过的链接颜色
    document.body.alink             //激活链接(焦点在此链接上)的颜色
    document.body.vlink             //已点击过的链接颜色
    document.body.text              //文本色
    document.body.innerText         //设置<body>...</body>之间的文本
    document.body.innerHTML         //设置<body>...</body>之间的HTML代码
    document.body.topMargin         //页面上边距
    document.body.leftMargin        //页面左边距
    document.body.rightMargin       //页面右边距
    document.body.bottomMargin      //页面下边距
    document.body.background        //背景图片
    document.body.a(oTag) //动态生成一个HTML对象
    
    location:子对象
    document.location.hash          // #号后的部分
    document.location.host          // 域名+端口号
    document.location.hostname      // 域名
    document.location.href          // 完整URL
    document.location.pathname      // 目录部分
    document.location.port          // 端口号
    document.location.protocol      // 网络协议(http:)
    document.location.search        // ?号后的部分
    
    常用对象事件:
    documeny.location.reload()          //刷新网页
    document.location.reload(URL)       //打开新的网页
    document.location.assign(URL)       //打开新的网页
    document.location.replace(URL)      //打开新的网页
    
    selection-选区子对象
    document.selection
    

    demo地址

    相关文章

      网友评论

      • Arthur澪:加载完毕后重新计算webview的高度,不准确。能否优化一下
      • 灯红酒绿映不出的落寞:求一个本文demo1242537720@qq.com. 请让加群啊大大
        若锦:@灯红酒绿映不出的落寞 你在webview的代理方法中点击图片的时候能打印出图片的链接么
        灯红酒绿映不出的落寞:@若锦 看到了。不过我试了一下我这边指定加载链接为什么里边的图片我点击不了呢,如果你有时间请帮我看看
        若锦:@灯红酒绿映不出的落寞 文末有个demo地址的,你仔细瞅瞅:joy:另外,我这边木有群哟
      • 游子_IT:求demo,佛说,分享是一种美德,479309088@qq.com🤗🤗
        若锦:@他是崔BB 我觉得如果工作量大的话没必要换吧,wkwebview也有其相应的代理方法,你在对应的代理方法中处理你想做的事情就行了
        游子_IT:@若锦 嗯嗯,想问你一下,我是刚接手别人的项目的,他之前用的是wkwebview,我现在怎么用你的换了他的?
        若锦:@他是崔BB 文末有demo地址,有需要的话可以下载看看哈,因为现在没法给你发:joy:
      • 布袋的世界:感谢,正需要这样子的一个功能!
      • 正直的豆豆:有个问题,就是html在这张图片加了超链接,那么点击图片会既展示图片也跳转,请问如何只跳转?
        若锦:@正直的豆豆 跳转的时候你判断一下,如果是图片的不要让它跳转链接。
      • 雪上踏痕:楼主能发我一个demo吗 724593302@qq.com谢谢
        若锦:@雪上踏痕 已发送,记得抽空查收,哈哈:smile:
        若锦:@雪上踏痕 现在需要的话可以从文末的下载地址去下载哈,或者明天再给你发:smile:
      • 不喜欢说话的小张同学:你这种做法有问题,,
        webview将scrollView.contentSize的高度设置为webView的height会导致内存占用骤增,,,!
        当加载一个网页高度非常大的网页会导致APP闪退,,,
        不喜欢说话的小张同学:@若锦 用wk'或者铺两层,前边是tableview后边是webview用table的滑动设置webview的contentsize
        若锦::joy: 嗯,那高度非常大时,你是怎么处理呢。
      • d0772cac6afe:同求demo,分享的人都是可爱的人0.0 , xiaoyanghb@gmail.com,O(∩_∩)O谢谢
        若锦:@young_0759 文末有demo下载地址,需要的话可以自己去下载哈:stuck_out_tongue_closed_eyes::stuck_out_tongue_closed_eyes:
      • 青是梦里:先谢谢大神分享,我加载完毕后重新计算webview的高度,但是计算出来的高度不对,这么办?
        若锦:@青是梦里 嗯,你是用的js计算高度然后相差很多么?你要不把计算高度的方法延迟一下试试
      • 口水电影:大神,求demo
        若锦:@口水巨多 已发送。其实文末有demo 地址,有时候可能消息处理的不及时:smile:
        口水电影:@口水巨多 2497033907@qq.com
      • 念念不忘的:有没有IMYWebView与JS交互的用法,大大。 :smile:
        若锦:@就叫我阿生叔叔吧 你是要跟网页进行交互吧,你可以进头文件中看看,有个wkwebview与网页交互的方法的;- (void)addScriptMessageHandler:(id<WKScriptMessageHandler>)scriptMessageHandler name:(NSString*)name;
        念念不忘的:可我调不出来这个方法
        - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {};
        若锦:@就叫我阿生叔叔吧 和webview 或者wkwebview 一样的用法就行:smile:
      • 旧时凉梦已成风:大神,同求代码,可否发到wangying@ccyuejia.com
        旧时凉梦已成风:@若锦 收到,谢谢
        若锦:@旧时凉梦已成风 发送到你的邮箱了,你查收一下。文末有demo地址,可以直接下载,有时候消息回复得可能没那么及时
      • 随风风流:在UIWebView中获取点击的图片链接有这个方法把js代码转成字符串 stringByEvaluatingJavaScriptFromString:
        请问在WKWebView中有哪个方法能够把js代码转成字符串呢。
        随风风流:@若锦 嗯嗯,只有这个方法,就是把block中的参数就是对应UIWebView返回的String,可以取出block中id数据进行使用。
        若锦:@随风风流 - (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ __nullable)(__nullable id, NSError * __nullable error))completionHandler;用这个方法处理js代码 :stuck_out_tongue_winking_eye:
      • b1eb368950d2:wkwebview可以加载本地资源么
        若锦:@ChanningKuo 可以的。
      • Q海龙:这种情况只适用短的webview 当你的webView内容区域很长的时候 图片很多的时候 会在webview撑开的时候闪退或内容区域变空
        Q海龙:这个问题我解决了 不做webview自适应高度 在本地html里写一个div放在你要放的位置 在通过js解决div高度 算下内容高度 再把相应的scrollview放上去 我的是webview加tableview 做完效果跟汽车之家的文章详情页一样 提供一个思路 如果有更好的解决办法 可以跟我说下
        Q海龙:@若锦 我现在的项目出现了这个问题 网页有长有短 短的话一点问题都没有 但是长的就不行了
        我这边项目还比这复杂 上面一个view是我的 中间webview 下边tableview 我试过好多方法 效果都能实现 但最主要的问题是如何能够很刘畅的滑动过度这几个控件 像 知乎 和 今日头条那样 现在还在尝试各种方法
        若锦: @45da2df2b974 嗯,内容多的话确实不太合适,你对于这个是怎么处理呢,富文本去处理么
      • YHWXQ简简单单的生活:大神,您好,可以发送demo到18500950595@163.com吗?谢谢!
        YHWXQ简简单单的生活:@若锦 谢谢,我也是之后才看到文末有demo :clap:
        若锦: @YH简简单单的生活 实在不好意思,这几天比较忙,没能及时看到消息。已经发你邮箱了,你抽空查收一下。其实文末有demo地址,哈哈。
      • d75492fc5568:求Demo 469770143@qq.com
      • d75492fc5568:给我一份demo 行吗??? 469770143@qq.com
        若锦:@ios小小朱 发你邮箱了,你抽空查收一下
      • 沐风一月:我的谢谢大神,我用uiwebview加载后台返回的html数据,因为做了图片适配屏幕。导致界面特别卡是不是因为图片宽高要一直重新计算,导致内存暂用太多才导致的?
      • 沐风一月:大神,求demo啊,614123580@qq.com
        若锦:@沐风一月 发送过去了,你抽空查收一下 :smile:
      • fba08aef555c:太牛了,求一份demo,邮箱1066643446@qq.com,拜谢大神
        fba08aef555c: @若锦 谢谢哈
        若锦:@ZXQ1234567 嗯,发送过去了,你抽空查收一下 :smile:
      • overla5:真勤奋啊,大大,一起来又看到一篇。:smiley:
        灯红酒绿映不出的落寞:求一个demo地址 1242537720@qq.com,还有请让加群哈
        若锦:@失格人间 哈哈,竟然又被你发现了 :smile:
      • Oniityann:zynfab26@hotmail.com,谢谢
        Oniityann:@若锦 谢谢
        若锦: @Oniityann 嗯,不用客气。已经发送过去了,你抽空查收一下。
      • lldb:大神,刚好要做这个东西,可否发送demo到496244139@qq.com,谢谢!:smile:
        若锦:@lldb 嗯,给你发过去了,你抽空查收一下。
      • timelee:大神,求demo。QQ 576263632@qq.com 多谢你的热心分享!!!! :christmas_tree:
        若锦:@timelee 嗯,发过去了,你抽空查收一下
      • c1011d4d14e6:求demo211126942@qq.com
        c1011d4d14e6:@若锦 谢谢你,你人真好!
        若锦:@简单如你 嗯,发过去了,你抽空查收一下
      • 乡水情缘:求demo ,QQ,1198928367@qq.com 谢谢你的分享
        若锦:@乡水情缘 嗯,不客气
        乡水情缘:@若锦 好的,谢谢你,可以加你微信吗?
        若锦:@乡水情缘 嗯,发过去了,你抽空查收一下
      • 许瘦子来世:求demo,QQ 1397223328@q'q.com,谢谢你的热心分享
        若锦:@gnhxsk 恩,不用客气。已经给你发过去了,你抽空查收一下 :smiley:
      • 谁是我我我:大神,求demo。QQ779442053@qq.com谢谢你的热心分享
        谁是我我我:@若锦 谢谢你。
        若锦:@谁是我我我 恩,发过去了,你抽空查收一下 :smiley:
      • 小楼东风:同求 demo 邮箱 820811266@qq.com
        谢谢。
        若锦:@小楼东风 恩,发过去了,你抽空查收一下 :smiley:
      • Jimsir:写的非常详细
        若锦:@Jimsir 嗯嗯,谢谢 :stuck_out_tongue_winking_eye:
      • 萌小奇:求本文代码的demo 谢谢 邮箱 deep_sea_fish@163.com
        若锦:@萌小奇 恩,已经发了,你抽空查收一下 :smiley:
      • 小小Q吖:同求 demo 邮箱 645203735@qq.com
        小小Q吖:@若锦 :blush::blush::blush:
        若锦:@就是拽嘿嘿 嗯,已经发了,你抽空查收一下 :smiley:
      • 垚子:maek
        若锦:@垚子 :smiley:
      • 3d153ddfdee3:求WKWebView 下载地址
        3d153ddfdee3:@若锦 谢
        若锦:@Codering 恩,文中介绍的IMYWebView的下载地址:https://github.com/li6185377/IMYWebView
      • fucuiping:求demo,谢谢 可以发到我邮箱吗 15131277173@163.com
        fucuiping:@若锦 十分感谢
        若锦:@fucuiping 发送过去了,你有空的时候查收一下:stuck_out_tongue_winking_eye:

      本文标题: iOS中加载HTML数据,并点击图片或链接进行相应的操作

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