cell中使用UITextView、UIWebView和WKWebView自适应显示html

    对于富文本(html标签)的显示,UITextView、UIWebView、WKWebView都能实现,首先针对不同显示控件来显示以下html标签

这是易企秀的一个h5链接 >>>请点击查看

UITextView实现代码

    //UITextView
    UITextView *testTextView = [[UITextView alloc]initWithFrame:CGRectMake(space, height + space, width - space * 2, height)];
    testTextView.backgroundColor = [UIColor whiteColor];
    testTextView.editable = NO;
    testTextView.delegate = self;
    testTextView.scrollEnabled = NO;
    testTextView.textContainer.lineFragmentPadding = 0;
    testTextView.textContainerInset = UIEdgeInsetsZero;
    [self.view addSubview:testTextView];

    NSData *data = [htmlString dataUsingEncoding:NSUnicodeStringEncoding];
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc]initWithData:data options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:nil];
    testTextView.attributedText = attrString;

UIWebView实现代码

   //UIWebView
    UIWebView *testWebView = [[UIWebView alloc]initWithFrame:CGRectMake(space, (height + space) * 2, width - space * 2, height)];
    testWebView.backgroundColor = [UIColor whiteColor];
    testWebView.delegate = self;
    [self.view addSubview:testWebView];
    [testWebView loadHTMLString:htmlString baseURL:nil];

WKWebView实现代码

    //WKWebView
    WKWebView *testWkView = [[WKWebView alloc]initWithFrame:CGRectMake(space, (height + space) * 3, width - space * 2, height)];
    testWkView.backgroundColor = [UIColor whiteColor];
    testWkView.navigationDelegate = self;
    testWkView.UIDelegate = self;
    testWkView.opaque = NO;
    [self.view addSubview:testWkView];
    [testWkView loadHTMLString:htmlString baseURL:nil];

运行显示效果图

    接下来我们考虑一个问题,如果在cell中显示富文本,并且自适应显示,富文本属于耗时操作,为了在cell中流畅显示,我们同时需要做好准备工作。UITextView控件数据的预测试代码

    NSString *htmlString = @"
不要相信任何所谓程序员说的:“HTML是用来做网页的”。这句话正确的描述是:“HTML是用于描述超文本的,网页是一个超文本资源节点”。HTML和网页本无联系 >>>请点击查看
"; NSMutableArray *array = [[NSMutableArray alloc]init]; for (int i = 0; i < 40; i++) { TestItem *item = [[TestItem alloc]init]; NSData *data = [htmlString dataUsingEncoding:NSUnicodeStringEncoding]; NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc]initWithData:data options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:nil]; item.attring = attrString; item.htmlString = htmlString; CGSize attrSize = [item.attring boundingRectWithSize:CGSizeMake(CGRectGetWidth([UIScreen mainScreen].bounds) - 40.0f, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil].size; item.htmlHeight = attrSize.height; } tableVC.dataArray = array;

代码说明:虽然测试用的固定字符串,但项目中一般不是固定的html字符串,所以我们对于格式一无所知,我们需要对拿到内容格式,我们通过转码的形式获取到富文本字符串,接下来通过该富文本获取到控件对应的数据,类似于方程求解,已知富文本,求富文本的高度

//size:屏幕宽度+两侧20.0f空隙
//option:NSStringDrawingUsesLineFragmentOrigin |NSStringDrawingUsesFontLeading;
//dict:富文本格式,下面具体说明
[htmlString boundingRectWithSize:size 
                         options:option 
                      attributes:dict 
                         context:nil];

首先看下富文本attrString

不要相信任何所谓程序员说的:“HTML是用来做网页的”。这句话正确的描述是:“HTML是用于描述超文本的,网页是一个超文本资源节点”。HTML和网页本无联系{
    NSColor = "kCGColorSpaceModelRGB 0.6 0.6 0.6 1 ";
    NSFont = " font-family: \"Times New Roman\"; font-weight: normal; font-style: normal; font-size: 14.00pt";
    NSKern = 0;
    NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 18/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
    NSStrokeColor = "kCGColorSpaceModelRGB 0.6 0.6 0.6 1 ";
    NSStrokeWidth = 0;
} >>>请点击查看{
    NSColor = "kCGColorSpaceModelRGB 0 0 1 1 ";
    NSFont = " font-family: \"Times New Roman\"; font-weight: normal; font-style: normal; font-size: 14.00pt";
    NSKern = 0;
    NSLink = "http://m.eqxiu.cc/s/D7LMUI03";
    NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 18/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
    NSStrokeColor = "kCGColorSpaceModelRGB 0 0 1 1 ";
    NSStrokeWidth = 0;
    NSUnderline = 1;
}
{
    NSColor = "kCGColorSpaceModelRGB 0.6 0.6 0.6 1 ";
    NSFont = " font-family: \"Times New Roman\"; font-weight: normal; font-style: normal; font-size: 14.00pt";
    NSKern = 0;
    NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 18/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
    NSStrokeColor = "kCGColorSpaceModelRGB 0.6 0.6 0.6 1 ";
    NSStrokeWidth = 0;
}

其实该文本的格式有3部分,3种富文本格式怎么计算高度,哎...即使可以估计也需要大量的时间,此处我们只取第一部分格式来计算整个文本的高度,方式有点牵强,但是对于格式较少时或许实用。我又尝试了另一种方法,通过UITextView的内容高度来直接获取,变更的代码如下:

     NSData *data = [htmlString dataUsingEncoding:NSUnicodeStringEncoding];
     NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc]initWithData:data options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:nil];
     item.attring = attrString;
     testTextView.attributedText = attrString;
     [testTextView sizeToFit];
     item.htmlHeight = testTextView.contentSize.height;

真机运行对比图:

两种方法对比图

总结

    方法1的不确定因素太多,计算出的高度误差比较大,特定场景下使用。

    方法2虽然在临界位置存在误差,但较小,对整体布局影响较小,可以采取微调方式使其完善,方法2也存在弊端,由于是通过显示的方式计算高度,会影响数据的刷新时间,但是实际使用后,发现影响较小,感觉不到刷新变慢,由于该数据是在网络请求解析后处理,与网络请求比,消耗时间不是很明显,此处可以留个疑问,以后有更好的方式,加以补充。

    方法2还有更强大的地方,就是它能显示webview中的内容,比如图片等,可扩展性比较好。

    有个疑惑点,模拟器返回的contentSize的高度不正常,而真机一直没问题。

    在cell中使用UIWebView或者WKWebView很少见,主要原因是cell高度的确定,webView高度只有在加载完成后才能准确计算,滑动会卡顿。
UIWebView加载完成方法:

- (void)webViewDidFinishLoad:(UIWebView *)webView
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error

WKWebView加载完成方法:

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error

在完成、失败方法中添加回调方法。

你可能感兴趣的:(cell中使用UITextView、UIWebView和WKWebView自适应显示html)