对于富文本(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
在完成、失败方法中添加回调方法。