针对HTML字符串,可以用UIKit框架中的UILabel 、UITextView。
WebKit中的UIWebView、WKWebView都可以显示HTML字符。
先分别看一下实现方法。
UILabel 、UITextView
NSString *html = @"<span style=\"font-size: 18px;\">看到了没有?</span><br/><p><img width='100%%' height='auto' src=\"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1536307082986&di=71ee1725f4519c99a5714b36206f2d3a&imgtype=0&src=http%3A%2F%2Fimg.juimg.com%2Ftuku%2Fyulantu%2F120414%2F2980-120414155H918.jpg\" title=\"\" alt=\"4da9754bd21cd8318ddaa20032a77a92.jpg\"/>内容3</p><br/><span style=\"font-size: 18px;\"> 没事</span><br/>有有有<br/>";
//这个是UILabel
NSAttributedString *attri = [[NSAttributedString alloc]initWithData:[html dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
self.titleLabel.attributedText = attri;
//这个是UITextView
NSAttributedString *attri = [[NSAttributedString alloc]initWithData:[html dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
self.textView.attributedText = attri;
从上面的方法大家都可以看到UILabel、UITextView它们都有一个属性attributedText。
而NSAttributedString中的可选NSDocumentTypeDocumentAttribute它可以绘制4种文本格式。
先看一下官方的定义。
// Supported document types for the NSDocumentTypeDocumentAttribute key in the document attributes dictionary.
//普通文本
UIKIT_EXTERN NSAttributedStringDocumentType const NSPlainTextDocumentType NS_AVAILABLE(10_0, 7_0);
//富文本
UIKIT_EXTERN NSAttributedStringDocumentType const NSRTFTextDocumentType NS_AVAILABLE(10_0, 7_0);
//带附件的富文本
UIKIT_EXTERN NSAttributedStringDocumentType const NSRTFDTextDocumentType NS_AVAILABLE(10_0, 7_0);
//可以加载HTML格式的文本
UIKIT_EXTERN NSAttributedStringDocumentType const NSHTMLTextDocumentType NS_AVAILABLE(10_0, 7_0);
这里要特别注意一下,titleLabel.attributedText 与 titleLabel.text 差不多一个意思。所以其他所有属性还是归UI组件本身控制的。例如UILabel中的numberOfLines是控制显示行数的,如果你发现只绘制了一行,写上以下方法就可以了。
self.titleLabel.numberOfLines = 0;
现在大家把代码贴上去运行一下会发现,图片怎么会显示不完???
图片显示不完.jpeg
NSString *html = @"<span style=\"font-size: 18px;\">看到了没有?</span><br/><p><img width='100%%' height='auto' src=\"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1536307082986&di=71ee1725f4519c99a5714b36206f2d3a&imgtype=0&src=http%3A%2F%2Fimg.juimg.com%2Ftuku%2Fyulantu%2F120414%2F2980-120414155H918.jpg\" title=\"\" alt=\"4da9754bd21cd8318ddaa20032a77a92.jpg\"/>内容3</p><br/><span style=\"font-size: 18px;\"> 没事</span><br/>有有有<br/>";
重点来了,大家可以看到上面的HTML。它的最外层是没有明确宽度是多少的,大家学过一点网页的都知道,一个页面它起码也是要有<html><head><body>等标签的。
图片那里宽度是width='100%%' ,但是最外层是多大?并没有明确指定,这里就会按照原图大小显示。所以我们就要把这段HTML代码给补全了。
/**
适配HTML Body宽度为指定大小
@param width 宽度
@return result
*/
- (NSString *)htmlAddbodyWidth:(CGFloat)width html:(NSString*)html{
NSString *tempHtml = [NSString stringWithFormat:@"<html><head></head><body style=\"width:%f;height: auto;\">"
"%@"
"</body></html>",width,html];
return tempHtml;
}
重新写一下完整的例子
NSAttributedString *attri = [[NSAttributedString alloc]initWithData:[[self htmlAddbodyWidth:[UIScreen mainScreen].bounds.size.width-56 html:html] dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
self.titleLabel.attributedText = attri;
这样就可以完整的显示了
图片显示完整.jpeg
再提供多一种选择吧,直接去修改图片的样式的方法,也可以提取HTML图片中的路径。下面的方法我是写在NSString的装饰类中的,需要的自己修改一下就可以了。
/**
过滤HTML字符串中的图片指定宽度
@param width 宽度
@return result
*/
- (NSString *)htmlWebAutoImageSizeWidth:(CGFloat)width{
if (self == nil || self.length == 0) {
return @"";
}
NSString *content = [self stringByReplacingOccurrencesOfString:@"&quot" withString:@"'"];
content = [content stringByReplacingOccurrencesOfString:@"<" withString:@"<"];
content = [content stringByReplacingOccurrencesOfString:@">" withString:@">"];
content = [content stringByReplacingOccurrencesOfString:@""" withString:@"\""];
NSString *html = content;
NSString * regExpStr = @"<(img|IMG)[^\\<\\>]*>";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regExpStr options:NSRegularExpressionCaseInsensitive error:nil];
NSArray *matches = [regex matchesInString:html
options:0
range:NSMakeRange(0, [html length])];
//HTML中的<img ...... />数组
NSMutableArray *imgArray = [NSMutableArray array];
//<img src="URL"/>中的URL数组
NSMutableArray *urlArray = [NSMutableArray array];
for (NSTextCheckingResult *result in matches) {
NSRange range = result.range;
NSString *group = [html substringWithRange:range];
NSRange srange1 = [group rangeOfString:@"http"];
NSString *tempString1 = [group substringWithRange:NSMakeRange(srange1.location, group.length - srange1.location)];
NSRange srange2 = [tempString1 rangeOfString:@"\""];
NSString *tempString2 = [tempString1 substringWithRange:NSMakeRange(0,srange2.location)];
[urlArray addObject:tempString2];
[imgArray addObject:group];
}
for (int i = 0; i < imgArray.count; i++) {
NSString *string = imgArray[i];
html = [html stringByReplacingOccurrencesOfString:string withString:[NSString stringWithFormat:@"<img src=\"%@\" title=\"\" alt=\"%lld\" width=\"%f\" height=\"auto\">",urlArray[i],[NSDate timeStamp]+i,width]];
}
return html;
}
再来看一下WebView是如何显示的呢?
UIWebView、WKWebView的实现方法。
NSString *html = @"<span style=\"font-size: 18px;\">看到了没有?</span><br/><p><img width='100%%' height='auto' src=\"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1536307082986&di=71ee1725f4519c99a5714b36206f2d3a&imgtype=0&src=http%3A%2F%2Fimg.juimg.com%2Ftuku%2Fyulantu%2F120414%2F2980-120414155H918.jpg\" title=\"\" alt=\"4da9754bd21cd8318ddaa20032a77a92.jpg\"/>内容3</p><br/><span style=\"font-size: 18px;\"> 没事</span><br/>有有有<br/>";
[_webView loadHTMLString:html baseURL:nil];
同理,如果图片显示不完一样要补全HTML!!!
那在实际项目中用那一种实现方法好呢?下面就来总结分析一下。
总结:
1、如果只是显示文本并不会有与用户交与的操作,建议是用UILabel、UITextView去显示HTML文本。因为这样系统可以很流畅的渲染UI,并不会卡顿。特别是在UITableView中的Cell自适应高度显示。
2、如果涉及到点击图片要求放大显示、其他交互等,那就用WKWebView。WKWebView它渲染UI的时间比较长,体验不怎么好,就相当于打开一个网页那样,是要等待的。并且呢在cell中做自适应显示难度是比较高的。(我有几个思路,但并没有实现过)。
网友评论